您最反对函数式编程的观点是什么?[关闭]


25

函数式编程是最古老的编程范例之一。但是,与更流行的范例相比,它在业界使用不多。但是在学术界已经大大强调了这一点。

您最反对函数式编程的观点是什么?


5
LINQ?.NET代表?像Mathematica这样的DSL?
乔恩·哈罗普

5
顺便提一句,“功能性编程”一词被不同的人使用,表示不同的事物,因此您需要弄清所使用的含义。
乔恩·哈罗普

2
您将永远找不到在您的功能代码库上进行编码的人。这不是一个伟大的商业决定,这限制了您的人才储备。
Patrick Hughes

Answers:


52

问题在于,最常见的代码固有地涉及状态-业务应用程序,游戏,UI等。应用程序的某些部分纯功能没有问题;实际上,大多数应用程序至少可以在一个方面受益。但是,将范式强加到处都是感觉违反直觉的。


19
绝对。纯函数式编程不太适合非常面向状态的应用程序。这就是为什么我喜欢可以同时使用这两种语言的混合语言的原因。对功能性问题使用功能性范式,对命令性问题使用命令性范式。
马特·奥莱尼克

8
同意!状态是编程的重要组成部分。这就是为什么即使是Haskell,在某些方面,最纯粹的FP语言,也允许使用状态和IO-它只是在IO代码/可变状态代码与纯代码之间建立了区分,这对于测试和易于理解非常有用。 。
条例草案

8
这就是为什么我爱Haskell。它鼓励最小化那些有状态的代码。在OO中,我旨在编写可重用,易于理解和易于测试的代码。在大多数情况下,我最终得到的代码不会在Haskell中写太多不同。
LennyProgrammers

4
“它只是在IO代码/可变状态代码与纯代码之间进行区分,这对于测试非常有用”。您甚至无法绕过类型系统或引入单子蠕变就无法打印调试消息。
乔恩·哈罗普

2
大概一个纯函数程序通过运行会完全改变世界?
马丁·贝克特

24

函数式编程的问题不在于函数式编程本身,而是大多数执行此操作的人和(更糟糕的)大多数设计用于执行该操作的语言的人。

问题源于以下事实:尽管非常聪明(有时是彻头彻尾的聪明才智),但仍有太多人对纯正,完美和对世界的看法(通常是相当狭and的)过于狂热,并向世界编程。语言以及使用它的每个人。

结果之一是无法妥协。(除其他事项外)这导致大约10,000种语言和方言的不同,足以使人烦恼,但只有极少的不同,以使其中一种具有与其他语言相比真正的显着优势。许多人还着眼于现实世界,并决定由于它与功能模型不太吻合,因此基本上是错误的,最好予以忽略。

无法妥协还导致了相当多的语言,它们对于特定类型的问题(或某些特定类型的问题)绝对是美丽的,但对于其他许多类型来说却确实很烂。其中一些可能是由功能模型本身引起的,但是(至少在我看来)更多是由吸引该领域的基本人格类型引起的。

这导致了许多问题。首先,学习“函数式编程”主要具有哲学价值。对于大多数其他类型的语言,了解特定类型的一种语言对学习另一种语言有很大帮助。如果我的项目使用语言XI,通常可以聘请相当安全地了解语言Y(但不是X)的人。对于函数式语言,事实并非如此。您可能非常了解Erlang,但仍然发现Haskell monads完全陌生且难以理解。

将语言的数量与人才之间有限的可移植性相结合,您会遇到一个丑陋的情况:一种语言或方言几乎不可能形成将其合理地普遍使用所必需的“临界质量”。这是慢慢改变,但它仍然像Linux一样成为占主导地位的桌面操作系统有很多-每一年,人们想出了令人信服的论据最后这将是一年-就像人谁一直在预测,每几十年来,他们又会错了。这并不是说(任何一个)都不会发生-只是那些看过预测并认为“不,今年不是”的人到目前为止是正确的。


4
如果功能语言更多,功能语言之间可能会有更多的交叉。
巴里·布朗

5
没有那种纯洁,您将无法“发挥作用”。一旦跨过这条线,整个概念就会瓦解,最终会产生混乱,并行,标准的语言,而没有任何优势。
Patrick Hughes

7
所以,你的第一个问题就是函数式语言没有不同的,足有超过对方的优势,你的第二个问题是,他们是不同之间的轻松去?
迪洪·杰维斯

2
对我来说,这个答案听起来像是在咆哮。如果要举一些例子,您的论点将更具说服力。
本杰明·霍奇森

1
...roughly 10,000 languages and dialects that are enough different to annoy but only rarely enough different for one to have a truly significant advantage over the others...不,听起来像所有这些程序语言。Java,Scala,Kotlin,C ++,C#,Groovy,Cheddar,ES6,Ceylon,Python等等,它们不胜枚举-它们只是无聊的C迭代,无法解决真正的问题。这是我的担保意见,以补充此担保答复:D
cat

17

我认为函数式编程没有得到广泛使用的原因是因为它妨碍了您的工作。很难认真研究一下例如Lisp或Haskell,而不必说“整个语言是一种很大的抽象反转”。当您建立了必要时编码人员无法获得的基线抽象时,您会建立该语言根本无法做到的事情,并且该语言的功能越多,它们所拥有的往往就越多。

以Haskell为例。以功能纯净的名义,您需要使用任何人都无法理解的令人震惊的抽象反转来管理状态和I / O,这是任何与任何事物交互的计算机程序的两个最基本的部分! 很快变老了。


9
+1,尽管有时我在使用高级命令式语言编程时会有相同的感觉。例如,为什么fsck我需要制作一个在Java中实现单个方法接口的单一方法类,而不是像在C语言中那样仅使用函数指针?
dsimcha

14
我要说的不是让您“不能陷入”这些抽象中,而是要花很多工作。我们习惯于捡香蕉并用命令性语言来吃它。Haskell(例如)让您首先填写20页的表格,因为它优先考虑的是确保您不看时不会神秘地吃掉香蕉。这在推理香蕉时会有所帮助,但有时您只是饿了。
j_random_hacker 2011年

4
@dsimcha:这是Java的特性,而不是高级命令式语言的趋势。实际上,高级语言可能更可能具有作为一流对象的功能。
Muhammad Alkarouri 2011年

3
Haskell中使用monad的必要性不在于功能纯净,而在于副作用和懒惰的评价是两种味道不佳的味道。Monads强制顺序评估。(实际上,它们应该被称为Computation Builders之类的东西。“ Monad” 对类别理论家以外的任何人来说都是个名字。)而且,您可以在没有(知道使用)monad的情况下愉快地进行FP!
Frank Shearar 2011年

4
需要注意的一件事:给定这些“抽象反转”,语言可能会受到更多限制,但是编译器和运行时对代码的保证更多,并且可以做更多的事情。这就像垃圾回收一样-在gc语言中,您不能只是malloc空间(这可能是有用的),但是作为回报,运行时可以为您管理所有内存,可能比手动管理更有效。功能纯度相同。
蒂洪·耶尔维斯

8

一切适当的尊重,我认为你的问题提出来了。函数式编程是一种工具,或者是一组对解决某些类型的问题有用的工具。对它有意见仅在特定问题或应用程序的上下文中才有意义。通常,对它有意见,就像对钳子或扳手有意见。


4
从逻辑上讲这是正确的,但是可以通过在OP问题的最后一句中加上“针对您经常遇到的编程问题的类型”来解决。(无关紧要的是,每个读者遇到的问题都可以,只要他们描述了自己的情况即可。)
j_random_hacker 2011年

4

即使我已经掌握了它,我也可能不愿意在商业产品中使用功能语言,原因很简单,原因是它们未被广泛理解,并且如果我希望业务发展,我会担心寻找其他有能力的开发人员的能力随着时间的推移维护或扩展它。

这不是不可想象的,您可能会获得更高的开发人员标准,因为没有真正黑客技能的javaschool毕业生不会知道从哪种类型的项目开始,但是有能力的开发人员的有限一定是一个必要的考虑因素。从业务角度来看。



2

首先,我不接受有关有状态编程和fp的任何论点。查看haskell中的State monad,您会发现许多有趣的新方法来评估State对代码的影响。

如果我要对fp进行有意义的论证,那将是学习像haskell这样的严肃的功能语言就像学习驾驶一级方程式赛车。...令人振奋和有教育意义,但对于日常的工业编码却很可惜,因为平均而言,您的同事正在驾驶凯美瑞,并且对此感到非常高兴。在fp友好的环境中找到工作仍然非常困难,而且除非有人愿意自行淘汰或寻找fp的一些知名从业人员,否则我不会看到这种变化。

我想我的回答让我觉得自己是fp的狂热粉丝。我建议在担心找不到原因的原因之前,先给haskell这样的真正的FP语言打个招呼。


6
我认为您的第一段完全描述了FP思维方式的问题。我们不希望 “采用有趣的新方法来评估状态对我们的代码的影响”。那有什么意思?!?我们只希望状态存在并且易于访问,因为我们需要它来实际完成任务。
梅森惠勒

2
我驾驶的凯美瑞(Camry)有问题,但不需要我经常检查引擎盖下是否有空间泄漏。Haskell更像是一种看起来像F1汽车的语言,但实际上并不能在持续的一段时间内进行高转速。:-P
j_random_hacker

1
@Mason Wheeler:“我们不希望使用有趣的新方法来评估状态对我们代码的影响。” 取而代之的是,我们宁愿花一个星期的时间来追踪由于不良副作用(我是根据个人经验)的一个非常讨厌的错误。
乔治

@brad clawsie:我认为控制FP中副作用的整个问题可以使编码效率更高:编写时间更长,但修复时间更少。不幸的是,必须首先投入大量精力进行学习,而且许多程序员没有这种长期思考:必须快速完成工作。第一次没有时间正确执行此操作,但是以后总是有时间进行调试和修复。:-)
乔治

@Mason Wheeler:从功能的角度来看,具有共享状态仅对优化有用:复制周围的值会花费过多的时间和内存,因此共享数据对象以避免不必要的复制。但是从一开始就强制执行共享状态是一种过早的优化。
乔治

2

我是函数式编程的忠实拥护者和拥护者。但是,这是我的观点:

  • 易于学习
    像python和ruby这样的编程语言(以及许多其他语言)也很容易学习。使用Haskell,Agda,Coq,ATS等语言进行高级功能编程非常困难。有些使用术语“数学结构化编程”。如果您熟悉类别理论和抽象数学,这很容易,但是如果您不知道“单子”是什么,那么可以做很多工作。

  • 使用脚本语言进行编程可以提高工作效率。
    在某些情况下,使用脚本语言(如python和ruby)可以提高生产力。这意味着可以快速制作原型并将不同的软件包或库粘合在一起。在这种情况下,即使使用动态语言(例如,面向对象的动态编程)也是一件好事。通常,静态类型更好,但是使用动态类型的脚本可以起到积极的作用。

  • 商业考虑
    编程只是成功的软件项目的一小部分。软件必须运行,用户必须开心,这不一定取决于所使用的编程语言。管理人员在评估新技术和编程语言时必须考虑收益和风险。新程序员可以快速学习新的编程语言吗?公司在技术方面有经验吗?是否存在风险,与上层管理人员难于争论吗?

在业务环境中,功能性编程可用于添加到核心软件组件(例如,并非如此关键任务的组件)的系统中。例如,一家银行几乎不会更改核心软件,而是以新的编程语言添加新的部件(GUI,监视软件等)。(也许有例外,但这是我在银行的经历。)

此外,当形式验证是一种好处或必须时,函数式编程非常有用。


3
“易学”:掌握Haskell并不比掌握现代C ++困难。我认为我们倾向于认真考虑我们不熟悉的事物。
乔治

1

我不反对FP是有用的范例,但我反对FP是编程语言中唯一可用的范例。

它在解决许多问题方面具有优势。但是,FP可以并且已经在C等程序语言中应用。


同意第一句话,不同意第二句话。没有垃圾收集,您基本上无法执行FP。
dsimcha

不需要语言的运行时系统缺少透明的内存管理(带有垃圾回收)以适合“过程”标签,因此具有讽刺意味的是,您用这种方式写了第二句话。BASIC是这样一种语言。
2011年

“基本上,没有垃圾收集就无法执行FP。” -为什么?
quant_dev

+1最基本的功能编程是无状态编程。我认为没有某种语言无法在某种程度上做到这一点。我已经用C,C ++,Java,汇编,C#甚至是Basic编写了函数。所需要的只是该函数没有副作用或在调用之间保持状态。
Michael K

另一方面,如果您的语言是完全纯净的,则编译器在优化方面还有更多余地。而且,代码变得更易于测试和推理。与混合方法相比,始终具有功能性确实带来了一些好处。如果您无论如何都将大部分代码设为无状态,则不妨再做进一步尝试,以获取更多好处。
迪洪·杰维斯

1
  1. (到目前为止,最重要的一点)程序员的劳动力没有经过这些语言或样式的培训
  2. 许多实用的福音传教士由于尝试销售实用的方式而成为洞洞或水果蛋糕。没有人喜欢一个洞,也没有人会把钱扔在一个水果蛋糕后面。提醒您,我真的很喜欢这些功能性的东西,并且希望将其引入其中,但是我知道,在我的工作场所中,我将是唯一一个无需花费大量培训(硬性销售)就可以开发它的人,几乎所有的优点引用读者的谈话内容。

当我们拥有数百个内核并达到锁无法扩展的认识时,功能便会出现。然后,并行数据嵌套将是“大型”程序的唯一途径,而功能在这方面表现出色。


0

FP在学术界很不错,因为编写出色的简短程序很酷,却忽略了性能。在现实世界中没有任何阴谋。同样,例如,实现某些东西(例如基数排序)似乎在FP中完全痛苦。哦,生成的代码是IMHExperience sloooooooooooooooooooooow。


4
是的,那显然是不正确的。Haskell代码通常可以与C和Java媲美,并且比Python和它的朋友要快得多。并行化通常也很简单,可能会提高速度。
迪洪·杰维斯

0

有些人的学习曲线相当陡峭,需要很长时间(特别是如果您来自OOP;在进行范式转换之前,您将数次尖嘴)。

即使我开始进行函数式编程(来自Java并进入Clojure),我仍然发现它相当困难。社区似乎没有编写像Java那样具有表现力的代码。

似乎表现力损失很小,复杂性增加很小。


我认为没有编程经验的人会说OOP的学习曲线比FP更陡,因为FP更接近于数学。我不理解您的意思是“社区似乎没有编写像Java那样具有表现力的代码”,您的意思是?
乔纳斯(Jonas)2010年

我从未听说过功能语言会失去表达能力。但是那时我也从来没有使用过比Java更少的表达语言,因此我对“表达性”的定义可能有所不同。
glenatron

@Jonas-因为一件简单的事情:函数,变量等的快捷名称...我的意思是,为什么不仅仅为它们的名称或应该做什么命名?为什么是“ pmap”?
Belun

1
@Belun:与函数式编程无关。您必须参考特定的编程语言。Map是许多函数式编程语言中常用的函数,并且具有很好的名称pmap您所指的可能是并行变量。
乔纳斯(Jonas)2010年

我说“社区似乎没有写作”。这意味着这就是我的经历,并体现了我所看到的社区。尽管我对此表示怀疑,但它并不一定适用于所有人。它也有与函数式编程的事,它就像它的风格
北仑

0

即使我对函数式编程语言(我认识一些Haskell和Lisp)经验很少,但我发现FP范例非常强大,并且通常比其他范例更优雅。我希望我有机会使用FP进行一个严肃的项目。

对于FP的有效性,我唯一有严重怀疑的领域是它如何处理无法归纳定义的复杂数据结构,例如图形。例如,如果我必须实现一种适用于大图的算法,可能遍历图并进行小的局部更改,那么我想知道FP方法是否可以与命令式方法相匹配,在该方法中,程序可以从节点移动到节点节点使用指针。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.