在C#中只编写等效于副作用自由编程的静态方法吗?

Jim*_*ffa 6 .net c# static functional-programming

我有两个问题,源于观察到的C#静态方法的行为(我可能会误解):

第一:递归静态方法在某种意义上是通过静态方法在封面下实现的方式进行尾调用优化吗?

第二:使用静态方法编写整个应用程序并且没有超出局部范围的变量,它是否等同于函数式编程?我很想知道,因为我仍然没有把这个"没有副作用"的术语包围起来,我一直听说功能性编程.

编辑:让我提一下,我确实使用并理解为什么以及何时在正常的C#OO方法中使用静态方法,并且我确实理解尾部调用优化不会明确地对递归静态方法进行.也就是说,我理解尾部调用优化是尝试在每次传递时停止创建新的堆栈帧,并且我在几个点观察到在它的调用方法的框架内执行的似乎是一个静态方法,尽管我可能误解了我的观察.

Dan*_*mov 6

在某种意义上,递归静态方法是否可以通过静态方法在封面下实现的方式进行尾调用?

静态方法与尾递归优化无关.所有规则同样适用于实例和静态方法,但我个人不会依赖JIT优化我的尾调用.而且,C#编译器不会发出尾调用指令,但有时它仍会执行.简而言之,你永远不会知道.

F#编译器支持尾递归优化,并在可能的情况下编译递归到循环.
在此问题中查看有关C#与F#行为的更多详细信息.

它是否等同于函数式编程用静态方法编写整个应用程序而没有超出局部范围的变量?

它既没有肯定.

从技术上讲,没有什么可以阻止你从Console.WriteLine静态方法(这是一个静态方法本身!)调用,这显然副作用.没有什么能阻止您编写一个不改变任何状态的类(使用实例方法)(即实例方法不访问实例字段).但是从设计的角度来看,这样的方法并不像实例方法那样有意义,对吧?

如果您Add是.NET Framework的项目List<T>(具有副作用),您将修改其状态.
如果您append将项目添加到F#列表,您将获得另一个列表,并且不会修改原始列表.

请注意,append确实List模块上的静态方法.在单独的模块中编写"转换"方法可以鼓励无副作用的设计,因为根据定义,即使语言允许,也没有内部存储可用(F#,LISP没有).但是没有什么能阻止你编写一个无副作用的非静态方法.

最后,如果您想要了解功能语言概念,请使用一个!编写运行不可变F#数据结构的F#模块比使用静态方法或不使用静态方法在C#中模拟相同更自然.