作为Java / C#/ C ++程序员,我听到了很多关于函数式语言的讨论,但从未发现有必要学习一种。我还听说过,功能语言中引入的更高层次的思维使您成为更好的OOP /过程语言程序员。
有人可以确认吗?它以什么方式提高了您的编程技能?
为了提高不那么复杂的语言的技能,学习语言的最佳选择是什么?
作为Java / C#/ C ++程序员,我听到了很多关于函数式语言的讨论,但从未发现有必要学习一种。我还听说过,功能语言中引入的更高层次的思维使您成为更好的OOP /过程语言程序员。
有人可以确认吗?它以什么方式提高了您的编程技能?
为了提高不那么复杂的语言的技能,学习语言的最佳选择是什么?
Answers:
我基本上同意FrustratedWithFormsDesign的回答,但您也询问如何学习新的范式有助于提高自己的技能。我可以根据自己的经验举几个例子。
自从学习函数式编程以来,我更加意识到与我一起使用的概念更自然地被视为“对象”(通常在有意义的情况下被视为对象),而更自然地被视为不可变的“值”(我认为有一个重要区别,探讨OO的意义与FP的意义,但这只是我的看法。
我注意到我的代码在哪些地方包含副作用,因此我更加谨慎地将那些地方隔离开来,使我的函数成为“纯”函数。这大大提高了我的OO代码的可测试性。
我对数据表示中的周期更加了解。(例如,我认为您无法在Haskell中编写函数将链表转换为双链表,因此您会注意到该语言的循环更多。)避免循环会减少同步量您需要使数据结构在内部保持一致,从而减轻线程之间共享这些结构的负担。
我更可能依赖于递归(方案的递归循环结构很漂亮)。Dijkstra在《结构化编程说明》中谈到了这一点的重要性-递归算法非常直接地映射到数学归纳法,他建议这是从智力上证明我们的循环正确的唯一方法。(我不建议我们必须证明我们的代码正确,但我们越容易使自己做到这一点,我们的代码就越有可能是正确的。)
我更有可能使用高阶函数。约翰·休斯(John Hughes)的论文《函数编程为何如此重要》。它强调了采用函数式编程技术所具有的可组合性,其中高阶函数起着主要作用。
同样,正如Jetti的回答中所提到的那样,您会发现许多FP想法已被合并到较新的OO语言中。Ruby和Python都提供许多高阶函数,我听说LINQ被描述为试图将对Monadic理解的支持引入C#,甚至C ++现在都具有lambda表达式。
1 + 2
在数学上等价于2 + 1
,但1.+(2)
在实现上与2.+(1)
。使用操作比使用对象接口更自然地理解存在许多SW问题。
我不会说这是保证让你更好的OOP程序员,但它会向你介绍一种新的思维方式,而这可以让你更好的解决问题的一般,不只是在OOP方面。
学习功能语言-对我来说Lisp-在构建并行应用程序时确实很有帮助。功能方法(基于状态,无副作用)更容易同步,并且更容易使线程安全,因为它们仅依赖于其输入。这意味着您需要监视给定代码区域的唯一数据是您传入的参数。这也使调试更加容易。
Thread
对象...笨拙。
学习任何其他编程范例都会提高您的编程技能。当编程不是学术研究级的东西时(甚至经常如此),它基本上是解决问题的方法。一句话思考。各种范例是思考问题及其解决方案的不同方式。因此,不要仅仅将其视为“学习功能语言”。可以将其视为“学习思考问题及其解决方案的另一种方式”。然后,即使您从未真正使用过语言,也会看到学习语言的好处。
为了解决您的特定问题,我曾经是一名C ++程序员,那是在过去的日子里(在没有C ++标准之前)。我遵循所有常用的东西,并持有通过方法等等操作状态的对象。然后我偶然发现了Haskell并了解了其中的大部分内容。(我认为从来没有人真正地学习过Haskell。)在我的一位同事,即分配给我小组的测试人员,随手评论说我的代码变得更容易测试之前,这项练习似乎有些浪费。
发生的事情是,我开始使我的对象变得越来越不可改变。具有复杂可变状态的类开始被替换为通过更改克隆自身并返回新对象的类。共享对象开始被具有写时复制语义的对象所取代(因此给人以很多对象克隆的错觉,而没有内存开销)。除非绝对必要,否则功能没有副作用。“功能”的纯数学定义越来越普遍。当我探索越来越多的函数式编程空间时,所有这些自然就开始在我的代码中发生-没有意识的参与。
现在,我的目标是每两年学习至少一个新的编程范例(即使它只是像AOP这样的次要扩展范例),并且每个范例中至少要包含两种新语言(一种尽可能纯净,一种混合/实用) )。每个人都给了我新的智力工具,可以用任何语言将其应用于我的所有编程,因此,我认为花费在学习它们上的时间并没有浪费多少。
机器代码不过是一系列副作用-处理器直接执行的命令。C语言的副作用是不同的,而不是处理寄存器和物理硬件,而是处理一组抽象,然后让编译器完成所有脏活。C还使您可以在循环和if语句中构造副作用。C ++通过向语言添加OOP和一些急需的功能对C进行了改进。Java和C#添加垃圾回收,Python添加动态类型。
即使具有所有这些功能-这些语言的动态键入,垃圾回收等程序仍完全基于副作用。功能编程语言(例如Scheme,Clojure,Haskell和ML)完全不同,这些语言更接近于数学,而更接近于机器代码。而不是使用副作用,而是在函数周围传递值。
为了提高不那么复杂的语言的技能,学习语言的最佳选择是什么?
我建议Scheme,它是最小的,它已在MIT的旧入门编程类中使用。其他函数式编程语言很难学习。Clojure带来了Java的所有复杂性,ML带来了复杂的静态类型系统,Haskell有时被称为学术语言-对于初学者来说并不理想,等等。另一方面,方案很容易学习和理解。
它以什么方式提高了您的编程技能?
几乎所有高级编程语言都具有函数和递归-函数式编程所基于的概念。因此,您对FP的了解几乎在所有地方都应该有所帮助,但是,如果您真的想进行功能编程,则应该使用一种自然而高效的语言,而不是尝试根据自己的喜好来弯曲别人的语言设计,也就是说您应该使用函数式编程语言来进行函数式编程。