为什么函数式编程在业界并不流行?现在流行吗?[关闭]


61

在我上大学的四年中,我们一直在使用多种函数式编程语言来使用许多函数式编程。但是我也使用了很多面向对象的程序设计,实际上,在做自己的小型项目来准备我的第一份工作时,我更多地使用了面向对象的语言。但是我经常希望在执行这些项目时使用功能性编程语言进行编码。

但是,在寻找工作时,很少会遇到需要功能编程语言知识的工作。

为什么函数式编程语言在业界没有得到更多使用?如今,有关函数式编程语言的新闻很多,所以我想知道函数式编程现在是否在行业中流行起来?


3
在某种程度上,我不同意您提出问题的前提。受“功能语言”启发的语言功能已被添加到Java和JavaScript等语言中。实际上,JavaScript一直(在某些方面)一直是一种功能性语言,尽管很多人直到最近才意识到它。
MatrixFrog 2011年

1
@MatrixFrog:人们可能会问:“为什么在非功能性语言中添加一些功能性概念而不是采用成熟的FP语言,才能使功能性半途而废?毕竟,这种模式已经存在了很多年并且非常成熟。”
乔治

出于各种原因(包括向后兼容性,惯性等),世界不会切换到高级替代方案(而纯FP是更好的替代方案)。请考虑DVORAK键盘布局:触摸打字效率更高,但我们都坚持使用QWERTY,原因是软件太多与qwerty友好的快捷方式。
KolA

Answers:


38

我要说的是,函数式编程并不流行的原因之一是缺乏知识库。我的经验是,就实施非主流技术而言,公司非常不愿意承担风险,而宁愿投资于久经考验的真实框架(java,c ++,c#)。只有在有业务需求时(例如在爱立信中),才考虑新的范例。但是即使在爱立信的案例中,我也听说管理层要求使用c ++,而Joe Armstrong被迫用c ++编写erlang调用代码!这应该显示出公司多么不情愿实施新技术!


9
函数式编程在任何方面如何“新颖”?
Evan Plaice 2010年

7
我认为他的意思是“未使用”而不是“新”。
Vinko Vrsalovic

9
所以它没用...因为它没用?嗯
亚历克斯·巴拉诺斯基

21
@Alex-没错。糟透了,不是吗?
KeithS

5
@ Stargazer712:那是什么原因?我认识许多不了解函数式编程的开发人员,所以无知对我来说很有意义。在过去,函数式编程是否曾发生过大规模的失败,使整个行业从我不知道的地方中消失了?
肖恩·麦克米兰

67

我曾经是一名教授,就像程序员一样,教授们一直在寻找下一个大东西。当他们以为自己找到了一个,就把它当成潮流,每个人都在堆积如山。由于他们向认为教授必须非常聪明的学生讲道,否则他们为什么会当教授,所以他们没有抵抗力。

函数式编程就是这样的潮流。当然,这里有很多有趣的问题需要调查,还有很多有趣的会议文章要写。这不是一个特别新颖的想法,您几乎可以使用任何现代语言来实现,并且不必变得有趣就可以成为新想法。这也是一项很好的技能。

鉴于此,函数式编程只是箭袋中的一支箭,而不是唯一的一支箭,就像OOP并不是唯一的一支箭一样。

我与计算机科学学术界的牛肉缺乏与行业的实际互动,无法确定实际意义上的意义,即质量控制。如果存在那种质量控制,那么可能会以权衡的方式,而不是最新的潮流,将重点放在对问题及其解决方案的分类上。


1
这是一个非常好的评论。+1箭袋中的箭头,以及权衡取舍的解决方案范围。
2011年

2
质检+1。海安会是多少更多有用的专用科目覆盖测试,代码审查,代码的复杂性和相似。能够自动验证程序在上一个补丁程序之后应做的事情与任何数量的“它应立即工作”手工波浪胡言乱语是值得的。
l0b0 2011年

5
@ l0b0:谢谢,尽管实际上我在考虑所教的内容和方法的质量控制。实际上,CS教授只是教他们个人觉得最有趣的事情。相比之下,与工业或医学相互作用的工程学或与现实世界相关性很高的医学。IME,CS专业人士认为,现实世界将对现实世界中的重要内容进行教学,但是学生并不急于学习-而是他们渴望将自己最兴奋的东西归于己见。
Mike Dunlavey

@迈克:几乎任何现代语言?您是否包括C ++和Java?
凯文·克莱恩

+1。我自己不能说的更好。
riwalk

25

因为如今软件开发中最大的问题是管理复杂性的能力。这不是大多数功能编程语言的重点。这样,确实具有优先权的语言(即更流行的OOP语言)往往会窃取某些更高级的功能语言所提供的一些更酷的功能,因此始终处于领先地位。


48
我不同意。函数式编程语言试图将状态的使用减至最少,从而使状态的复杂度降低。用功能语言编程的程序也更易于测试和重构。
乔纳斯(Jonas)2010年

7
@Jonas:许多程序员发现编写几乎完全不使用状态的程序非常困难(包括我自己)。从这个角度来看,它实际上更复杂。(请注意,我不会以任何方式讨论函数式编程的用处!)
ShdNx 2010年

3
@ShdNx:是的,我知道。甚至在我上大学时,我就认为函数式编程很困难。但是过了一会儿,我开始更喜欢命令式编程和更具体的OOP。在我的大学里,函数式程序设计是在命令式编程之前进行的,而在大学之前没有做过任何编程的学生就认为,命令式编程一开始非常困难,而函数式编程更接近于数学。
乔纳斯(Jonas)2010年

16
难度和复杂性之间是有区别的。OOP绝对比结构化编程困难,因为它增加了更多概念。对于足够大量的代码,它们通过提供代码结构来降低复杂性。FP是同一回事:如果只写两行,那似乎有点过头了,但是如果您的代码足够大,则将代码结构化为无状态子单元可以提高可伸缩性并降低代码的复杂性。
Muhammad Alkarouri

6
函数式编程的主要重点之一是可组合性。如果那不是管理复杂性的工具,我不知道这是什么。
dan_waterworth 2011年

23

函数式编程肯定已经开始流行-缓慢但肯定地。

例如,由于以下原因,我正在构建的初创公司正在使用功能语言(Clojure)作为主要开发语言:

  • 生产力 -学习FP很难,但是一旦掌握了它,就很难在力量和表达能力上胜过。与我在C#或Java中所需的功能相比,我可能在写大约1/10的行数来实现任何给定的功能

  • 可靠性 -纯函数比有状态对象容易推理和测试。因此,您可以编写更好的测试并更轻松地验证代码的正确性。

  • 并发性 -功能语言强调不变性,与并发应用程序在多个内核上有效运行相比,它具有巨大的优势。无论您是否喜欢,在多核上运行都是未来。有关为什么这如此重要的简单解释,请参见http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey

  • 可组合性/模块化 -功能语言似乎比复杂的OO系统更容易将组件插入在一起。我仍然没有弄清楚造成这种情况的所有原因,但是部分原因是由于您没有OO模型拖延的所有“偶然复杂性”。斯图尔特·哈洛威(Stuart Halloway)关于“ 极简主义 ”的演讲更深入地探讨了这些想法。

编辑:作为对Despertar的评论的回应,限制模块化的OOP系统“偶然复杂性”的一个示例是深度克隆与浅层克隆的问题:您不能将对象组合在一起并以复合结构形式将它们作为复合结构传递仔细分析克隆和突变语义。在较小的情况下,这是可以管理的,但在复杂的系统中,它迅速成为一个重大问题。如果您依赖于纯函数数据结构,那么这个问题就不会存在。


+1,我很想听听您为何选择Clojure的决策过程。(我不是支持或反对Clojure,我只是感兴趣)。
dan_waterworth 2011年

4
“学习FP很难”:学习任何范例都很困难。我记得在我有足够的经验来提高工作效率之前,我花了几个小时使用命令式代码(Pascal)。我认为FP的知名度不高,因为许多程序员首先学习了命令式语言,而一旦他们学会了如何编程,他们就没有时间去看其他东西了。我是一名全职C ++程序员,目前正在下班后的晚上学习Scala。如果我有一个家庭照顾,我简直会忘记它。
乔治

1
我认为前3个案例很好,但是我不同意第4个案例。OOP是非常模块化和组合的;对我来说,这是它最大的优点之一。通过封装和抽象隐藏复杂性也很棒。
Despertar

1
@乔治 究竟。“学习FP很难,学习OOP容易”与“学习西班牙语很难而汉语很容易”一样荒谬。这取决于您的母语。而且我并没有选择中文作为OOP的任意类似物-因为OO习语就像象形文字:易于一一学习,但很难全部记住并且无法编写。FP更像是一种带有字母的语言:单独的字母在孤立中没有用,但允许以相当小的规则集
编写

1
(续)所以出于同样的原因,为什么它不受欢迎-至今。象形文字在第一个字母发明和成熟之前就已经存在。可能需要一代具有字母书写和阅读能力的一代人,我是说FP是他们的第一个范例
KolA

12

缺少杀手级应用

嘿,这边看起来很新鲜。(挖挖挖)

我认为大多数编程语言都是通过拥有“杀手级应用程序”而蓬勃发展的,这是该语言所独有的(或以这种方式来看)。这并不是说所有使用的语言都是应用程序,而是它使语言受到了更大的接受。

对于什么利基推动了我们今天使用的某些语言的采用,我的观点并不十分准确。

  • C:无处不在(这是70年代和80年代后期)
  • C ++:GUI框架(90年代初)
  • Java:Applet和Servlet(在90年代后期)
  • Objective-C:iOS应用(之前为OS X应用)
  • Ruby:Rails
  • C#:ASP.NET,WinForms
  • PHP:Wordpress等
  • Javascript:AJAX,尤其是通过框架
  • lua:游戏脚本,尤其是《魔兽世界》

除此之外,许多专有语言已经通过强大的销售组织(Oracle,以及程度较低的Microsoft语言)进入了大门,有效地建立了自己的利基市场。

关于该列表的一个非常重要的注意事项:杀手级应用程序指出,该语言的“利基”随着几十年的过去变得越来越具体。请注意列表中的最后一个:游戏脚本,特别是。由于另一种语言已经可以很好地完成工作,因此语言越来越难以引起人们的注意。

因此,任何功能语言真正需要起飞的都是一个利基市场。实际上,还没有任何强大的功能语言,但是在较小的领域有很多东西:

  • Emacs Lisp:自80年代以来,开发人员就在Emacs中不断使用它。(几乎从未在其他任何地方使用。)
  • Erlang:任何需要大量并发代理的地方。
  • 计划:教育
  • APL / J / K:财务(为方便起见,我们称其为功能性)
  • 常见的Lisp:“ AI”-人们倾向于说它的用途,这是一种祝福和诅咒。

现在,我觉得我脱离讨论的唯一主要语言是Python。Python做得很有趣。它没有在任何主要利基市场中脱颖而出而成功。这可能意味着我完全不赞成以这种方式查看语言流行度。这也可能意味着如果没有一款杀手级应用来推动采用和接受,那么一种足够好的语言可能会变得流行,但这是非常困难的,并且可能需要很长时间。(Perl也有类似的故事,但几年前就出现了,现在的普及率更低。)

由此,我可以说出我认为正在增长的功能语言:

  • Clojure:网络编程,尤其是。通过Heroku
  • Scala:提升(或者,最近可能是Play)-没有Java的JVM

如果您问我接下来在哪里可以找到流行的功能语言,那我想说的是寻找具有交钥匙型云开发(la Heroku或GAE)或交钥匙型移动应用程序开发的功能语言。


我也认为Perl是主要语言。我想说这是一种较旧的语言,最常用于类似Unix的系统。尽管Python似乎是一个更现代的选择。它仍然是一种流行的语言,已经引起了广泛的关注并拥有广泛的社区。
Despertar

1
@Despertar-我并没有特别努力就我提到的哪种语言而平等:)并同意,这个故事看起来很像Python,除了过去几年。
杰西·米利坎

1
Perl 确实有一些优势。最早的版本反映在其文档的较旧版本中,该文档的名称称为“实用提取和报告语言”的缩写。沿位的第二次来到后,又是CGI脚本-多年,perl的是网站的语言。显然,它现在已经失去了很大的知名度,但是看看那些仍在运行与最初使用它们的软件相同的软件上运行的旧网站,您会看到很多perl(我现在想到的是slashdot.org)。 ,但还有很多)。
Jules

8

出于同样的原因,Lisp从未真正流行起来(让火焰战争开始!)。与命令式和面向对象的编程相比,函数式编程是一种非常陌生的范例。如果像绝大多数CS学生一样,您从C入手,后来又发展为C ++ / Java,那么您倾向于不想学习与通常的思维方式完全正交的思维方式。


2
外星范式?它比命令式编程更接近数学。在瑞典,我认为大多数大学的CS学生都首先考虑功能编程。例如,我们从Standard ML开始,然后是C,Erlang和Java。
乔纳斯(Jonas)2010年

4
很公平。我知道,英国和印度的许多工程专业的学生首先会学习C语言,然后是C ++和/或Java。通常他们根本不教任何功能语言。
Chinmay Kanchi 2010年

13
@Jonas对于许多人来说,数学是一种外来的范式,凡是使编程远离数学的事物都可以使其更容易理解。
scriptocalypse 2011年

5
我听说过从未听说过树木的人,更不用说函数编程了,而且毕业了。
dan_waterworth 2011年

1
@ Tux-D,实际上,不,我是说英国的学生。
dan_waterworth

6

让我们考虑一下业务和编程。

有些企业将其软件用作战略资产。这不是典型的。对于大多数企业而言,IT可以支持公司的实际业务。这是必要的费用。他们之所以很保守,是因为他们知道只要花$ X就能获得所需的IT,而如果改用其他东西,那么如果一切顺利的话,他们将节省少于$ X的费用,而如果一切状况不佳的话,则将损失大量的钱。

此外,在企业中,最便宜的事情通常是他们昨天所做的事情。然而,期望改变是昂贵的。如果一家公司要从例如C#/。NET解决方案更改为F#,那么他们就会遇到问题。他们的程序员(可能不是那里最聪明的程序员)将必须学习一种新语言,并且精通这两种语言,并经常使用这两种语言。会有很长一段时间都用两种语言编写的例程。如果他们要迁移到Haskell之类的东西,或者如果他们首先使用C ++ / MFC,那么他们将进行更多的更改,这将花费更多。

另外,在很长一段时间内,将有大量的C#程序员和Microsoft的持续支持。当前的IT实践可以指望。没有同等水平的机构支持或程序员持续可用性的保证。

因此,对于大多数企业而言,对功能编程的更改在一开始就很昂贵,并且只有从长期来看,IT成本的降低足以使它自己得到回报,这才是值得的。


2

您已经以功能样式编写了代码,只是您不知道。

当需要对代码进行单元测试时,您倾向于编写可测试的函数,这些函数不创建也不依赖于副作用,并且始终在相同的参数上返回相同的结果(即所谓的纯函数)。这是功能程序的主要优点。

我认为函数式语言太局限了。因此,命令式语言可以代替功能性语言,而不必具有功能性。如今,几乎每种编程语言都有闭包和lambda。


1

我相信您的问题只有一个真正的答案。您可能会找到很多相关原因说明为什么找到这种答案,但这是不同的问题。

这里是:

  • 软件架构师提供了他们相信可以使用的解决方案。
  • 大多数架构师都不使用功能语言。
  • 一旦选择了技术和语言,企业就会找到可以与他们合作的人。

流行吗?这完全取决于对使用功能性语言有信心的人是否正在成为架构师,并选择将其用于他们从事的项目。


0

真正的问题是状态。

功能语言没有全局状态。大多数工业问题都需要大规模的状态(您如何表示分类帐或一组交易),即使小规模的某些功能实际上并不需要它(处理分类帐)。

但是我们正在Von-Neuman体系结构机器上运行代码,这些机器本质上是全状态的。因此我们实际上并没有摆脱状态,功能语言只是向开发人员隐藏了状态的复杂性。这意味着语言/编译器必须处理后台状态并对其进行管理。

因此,尽管功能语言没有全局状态,但它们的状态信息作为参数和结果传递。

那么问题就变成了语言可以在感觉背后有效地处理状态吗?尤其是当数据大小远远超过体系结构的大小时。

从硬件方面看

在过去的几年中,该操作系统在可视化地址空间方面提供了很多帮助,因此应用程序无需正式担心它。但是,当内存压力越来越大时,不必担心的应用程序就会陷入硬件崩溃的陷阱(硬件崩溃会使您的进程减慢爬行速度)。

由于程序员不能直接控制功能语言中的状态,因此他们必须依靠编译器来处理此问题,而且我还没有看到能很好地处理此状态的功能语言。

相反,全状态编程器可以直接控制状态,因此可以补偿低内存条件。尽管我还没有看到很多程序员足够聪明。

从行业角度看:

工业界有许多效率低下的全状态编程器。

但是很容易衡量这些程序随时间的改进。您使开发人员团队陷入一个问题,即他们可以通过改善程序处理状态的方式来改进代码。

对于功能性程序,这些改进很难衡量,因为您需要改进将改进程序的工具(我们只是在这里研究应用程序如何有效处理基础状态,而不是程序的整体改进)。

因此,对于行业而言,我认为这取决于衡量代码改进的能力。

从招聘的角度

有很多统计量充足的程序员可供雇用。功能性程序员很难找到。因此,如果行业转换为功能样式编程,那么您的基本供需模型就会启动,而这并不是他们想要发生的事情(程序员本身就足够昂贵了)。


2
功能语言,尤其是“不纯”功能语言,可以很好地处理全局状态。我发现程序经常分解为交替的层:例如全局状态...但是功能状态转换...偶尔具有局部(屏蔽)状态以实现这些转换的性能关键部分,等等。命令性语言的问题,IMO是,它们通常会导致程序员在功能模式更好地工作时不恰当地使用状态。但是语言似乎正在朝着很好地支持两种风格的方向发展。
Ryan Culpepper

1
用功能语言处理状态非常容易,但需要转移重点。在命令式语言中,您编写了修改状态的过程,而在功能语言中,您编写了返回修改状态的过程的函数。
dan_waterworth 2011年

“功能语言不具有全局状态”-您不需要全局状态。几乎所有状态管理都可以通过monad完成。
阿鲁纳夫·萨尼亚(Arunav Sanyal)'18年

-3

这个问题的前提有一点错误。由于以下原因:

  1. 函数式编程实际上在业界很普遍。但这仅在有经验的程序员可用的地方使用。不能期望初学者知道它。几乎所有大型编程项目都在使用它,但是它们只是将其保留在有经验的程序员处理的区域中。初学者将处理不需要功能编程的简单模块。
  2. 在这种情况下,雇用人员(通常是大学毕业的年轻人)的公司就不能真正要求功能编程经验。需要功能编程的项目中的任何人已经在同一家公司工作了15年。
  3. 大学开始教授它,因为他们现在已经知道函数式编程知识将在30年内非常有用。他们的时间范围是30年,而不是像公司那样正常的半年时间。
  4. 这些都是人们进入工作岗位后感到失望的原因,因为他们发现没有使用在大学学到的东西。但是它们的设计时间跨度为30年,最终将很有用-只是公司正在使用简单的东西-他们可以期望人们知道的东西。
  5. 如果您认为经过几年的大学学习,您对函数式编程非常了解,可以在实际的软件项目中使用它,那么您也会很自大。首先从简单的东西开始。开始工作时,您实际上并不需要做最复杂的软件作为第一个任务。您最终将了解复杂的内容,但这需要时间。

2
1) “几乎所有大型编程项目都在使用它”。我的经验是,这远非现实。据我所知,很少有公司使用函数式编程。大多数只使用Java和C#(即使最近几年C#具有更多的功能构造),C ++和
Jonas

2
2)我的经验正好相反。似乎只有大学的知道函数式编程。在瑞典,大多数大学从第一年开始就教授函数式编程。直到最近,像MIT这样的大学都在其第一门编程课程(方案)中使用了函数式编程。
乔纳斯(Jonas)

@jonas:不,编程语言与它无关。当然,大量项目都使用C和C ++以及Java等。函数式编程也可以用c ++代码进行。当前的实践似乎是该项目的一部分使用OO,而部分使用函数式编程。这两部分使用相同的语言(通常为c / c ++)
tp1

是的,您也可以在C中执行OO。但是不建议这样做。C和C ++没有太多用于函数式编程的构造,例如默认情况下不可变,对模式匹配没有很好的支持,不包含不可变数据结构等等……
Jonas

好吧,这就是为什么它需要经验丰富的程序员。由于从主流语言中更改编程语言几乎是不可能的,因此下一个最好的事情是使用c ++进行函数式编程。另外,c ++具有诸如const之类的功能,对您很有帮助。
tp1

-10

因为调试FP较难。


11
我不同意。没有附带影响,调试过程会更容易。也许您认为这很困难,因为功能范例是不同的,并且需要经验来适应新的工作方式,包括调试。
Maniero

2
函数式编程语言实际上更易于测试,因为纯函数是无状态的。
乔纳斯(Jonas)2010年

4
乔纳斯,我不是说“测试”,而是说“调试”。找到您犯的错误。测试是其中的一部分,但是有关程序的推理也是如此。bigown-我坚持这一点。这是FP功能的函数。任何特定代码行所做的工作越多,就越难确定哪一行代码会引起问题。代码行和效果之间的映射更加分散,例如。单个高阶函数可能涉及程序的数十种行为,反之亦然。对于相同的错误,症状可能在不同点之间变化很大。
星际

以我的经验,调试一点也不难。我正在使用F#,但找不到任何原因,例如,您会发现它比C#更难调试。由于懒惰(我不知道),在Haskell中调试可能会更困难,但正如Jonas所说的那样,由于无状态,急切的FP编程更简单。换句话说,FP代码更可预测,因为您知道结果不受未知变量的影响。
Muhammad Alkarouri

2
只要您的函数是纯函数,调试就很容易。如果您无法通过添加单元测试来进行调试,那么您就无法充分编写测试。
dan_waterworth 2011年
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.