为什么没有function性编程呢?
我已经阅读了关于声明性/函数式编程(语言)的一些文本,尝试了Haskell以及自己写的一个。 从我所看到的,函数式编程与古典命令式风格相比有几个优点:
- 无状态程序; 无副作用
- 并发; 对于不断上升的多核技术的玩法非常好
- 程序通常较短,在某些情况下更易于阅读
-
生产力提高(例如:Erlang)
-
命令式编程是一个非常古老的范式(据我所知),可能不适合21世纪
为什么使用function语言编写程序的公司仍然如此“罕见”?
为什么在研究函数式编程的优点时,我们还在使用命令式编程语言呢?
也许现在为时太早,但今天呢?
因为所有这些优点也是不利的。
无状态程序; 无副作用
真实世界的程序都是关于副作用和变异的。 当用户按下button时,这是因为他们想要发生一些事情。 当他们键入某些东西时,他们希望这个状态代替原来的状态。 当Jane Smith在会计学结婚并将其名字改为Jane Jones时,支持打印她薪水的业务stream程的数据库最好是处理这种变化。 当你向外星人发射机枪时,大多数人并没有将这种机器人的精神build模成一个新生命值较低的新外星人。 他们将这个模型作为现有外星人属性的变种进行build模。
当编程语言的概念从根本上抵制被build模的领域时,很难certificate使用该语言是合理的。
并发; 对于不断上升的多核技术的玩法非常好
问题只是被推动。 使用不可变的数据结构,您可能会使用过时的数据,从而具有廉价的线程安全性。 使用可变数据结构,您可以获得始终处理新数据的好处,但必须编写复杂的逻辑来保持数据的一致性。 这不像其中之一明显好于其他的。
程序通常较短,在某些情况下更易于阅读
除了阅读时间较长,难度较大的情况外。 学习如何阅读function风格写的程序是一项困难的技能, 人们似乎在将程序设想成一系列需要遵循的步骤(比如配方)而不是一系列要进行的计算方面好得多。
生产力提高(例如:Erlang)
为了certificate雇用懂function风格程序员的大量开销,生产力必须提高。
记住,你不想丢掉一个工作系统; 大多数程序员不是从头构build新的系统,而是维护现有的系统,其中大部分是以非function语言构build的。 想象一下,试图为股东辩护。 为什么要废弃现有的工资发放制度,以数百万美元的成本build立新的工作制? “由于function性编程非常棒”,不太可能令股东高兴。
命令式编程是一个非常古老的范式(据我所知),可能不适合21世纪
函数式编程也很旧。 我不明白这个概念的年龄是如何相关的。
不要误解我的意思 我喜欢函数式编程,我join了这个团队,因为我想帮助将函数式编程的概念引入到C#中,我认为编程是一种不可改变的风格,是未来的方式。 但是,function风格的编程有很大的代价 ,不能简单地被消除。 朝着更实用的方式转变将在几十年内逐渐缓慢地发生。 而这就是:向更实用的风格转变,而不是大规模地拥抱Haskell的纯洁和美丽,放弃C ++。
我为编译生成编译器,而且我们确实正在为下一代编译器工具提供function风格。 这是因为函数式编程从根本上来说是我们所面临的各种问题的一个很好的匹配。 我们的问题都是关于原始信息 – string和元数据 – 并将其转换为不同的string和元数据。 在发生突变的情况下,就像某人在IDE中键入内容一样,问题空间固有地适用于function性技术,例如逐渐重build仅改变树的部分。 许多领域没有这些很好的属性,使它们明显顺从function风格 。
程序devise大师:与主要编程语言的创造者交谈
[哈斯克尔]
为什么你认为没有函数式编程语言已经进入主stream?
约翰·休斯:糟糕的营销! 我不是说宣传; 我们有很多。 我的意思是仔细select一个目标市场利基来支配,其次是坚定的努力,使function性编程是迄今为止最有效的方式来解决这个利基。 在80年代的快乐日子里,我们认为函数式编程对所有的东西都是有好处的 – 但是把新技术称为“对所有事物都有好处”就像把它称为“特别无所事事”一样。 品牌应该是什么? 这是John Launchbury在ICFP的受邀演讲中非常清楚地描述的一个问题。 当他们的品牌是“function语言软件”时,伽罗瓦连接(Galois Connections)就差一点了,但是由于专注于“高保证软件”,他们已经不断发展壮大。
很多人不知道技术革新是怎么发生的,希望更好的技术能够自己独占优势( “更好的捕鼠器”效果),但世界却不是这样。
股票的答案是既不会也不应该取代另一个 – 他们是不同的工具,有不同的优点和缺点,哪个方法的优势在于项目和其他“软”问题,如可用的人才库。
我认为,当多function编程被select超过其他风格时,由于多核心的并发性增长将增加(全球开发项目集合)的百分比。
我认为今天很less见,因为今天的大多数专业人才库最适合使用命令式和面向对象的技术。 例如,我不止一次select了Java作为一个商业项目的语言,因为它足够好,没有争议,而且我知道我永远不会耗尽可以编程的人(非常好)。
尽pipe函数式编程有其优点,命令式和面向对象编程将永远不会完全消失。
命令式和面向对象式编程是对问题及其解决scheme的逐步描述。 因此,可以更容易理解。 函数式编程可能有点模糊。
最终,一个有用的程序总会有副作用(比如提供实际的输出给用户消费),所以最纯粹的函数式语言仍然需要一种不时进入命令式世界的方式。
当前最先进的技术是命令式语言(例如C#)从function世界(例如lambda语句)借用function,反之亦然。
不是吗?
Smalltalk当天是一个很好的面向对象系统。 为什么没有面向对象编程接pipe? 那么,它已经。 它看起来不像Smalltalk。 主stream语言在C ++,Java,C#等方面越来越像Smalltalk一样。时尚和风格变化比任何东西都慢,所以当OO成为主stream时,我们通过将OO的部分粘合到旧的语言来得到它,所以它看起来像C一样足以吞咽。
function是一样的。 哈斯克尔是一个伟大的function语言。 但是现在比20年前更多的主stream程序员使用类C语法。 所以它必须看起来像C.完成:看看任何LINQexpression式,并告诉我它不起作用。
我相信命令式语言更为stream行,因为这是更多人习惯的。 函数式编程和命令式编程模式都不是比其他模糊或学术更晦涩难懂的。 实际上,它们是互补的。
一个海报说,命令式代码比函数式编程代码更容易理解。 如果读者已经看到命令式的代码,特别是如果前面的例子是同一个“族”(例如,C / C ++,Perl,PHP和Java)的一部分,这是唯一的。 我不会说任何命令性的语言都是这样。 比较Java和Forth,做一个极端的例子。
对于一个非专业人士来说,所有的编程语言都是难以辨认的乱码,除了Hypertalk和SQL等冗长的语言。 (值得注意的是,SQL是一种声明性和/或function性语言,并且受到广泛的欢迎。)
如果我们从一开始就接受了Lisp-y或Haskell-y语言的培训,我们都会认为函数式编程语言是完全正常的。
你已经得到了足够的答案,我只提到一些我没有看到的东西。
首先(在我看来)最重要的是,程序语言从它们的共同程度上受益匪浅。 举一个例子,几乎任何几乎任何程度的主stream程序(或OO)语言的人都可以很好地阅读其他人的大部分。 我主动避免使用Java,C#,Cobol,Fortran或Basic(仅举几个例子),但是可以合理地阅读其中的任何一个,事实上,就像每天使用它们的人一样。
在function方面,这是不太正确的。 举个例子,我可以很合理地写Scheme,但是在Ocaml或者Haskell中只有很less的用处(仅举几个例子)。 即使是在一个单一的家庭(例如Scheme vs. Common Lisp),对某个家庭的熟悉程度似乎也不会太好。
只有在一个狭窄的条件范围内,function代码更具可读性的说法往往是正确的。 对于那些对这门语言非常熟悉的人来说,可读性确实非常出色 – 但是对于其他人来说,通常是不存在的。 更糟糕的是,程序语言的差异主要是语法上的,因此相对容易学习,而function语言的差异往往更为基本,所以需要大量的研究才能真正理解(比如,了解Lisp对理解Monad几乎没有帮助)。
另一个重点是function程序比程序化程序更短的想法通常基于语法而不是语义。 用Haskell编写的程序(例如)通常很短,但是它的function只是一小部分。 如果简单地说Haskell具有相对简单的语法,那么这很重要。
很less有纯function的语言可以和APL很好地竞争以获得简洁的源代码(尽pipe公平地说,APL也支持创build更高层次的function,所以与其他一些情况相比差别不大)。 相反,Ada和C ++(仅用于几个示例)在完成给定任务所需的操作次数方面可能相当具有竞争力,但语法(至less通常)更为冗长。
没有感知的需要
我回想起我的老板Rick Cline的回应,当时我向他展示了John Backus的图灵奖演讲题为“ 可以从冯诺依曼风格解放出来 ”的副本吗?
他的回答:“也许我们有些人不想从冯·诺依曼风格中解放出来!”
为什么没有function性编程呢?
function对某些事情更好,对其他事情更糟,所以它永远不会“接pipe”。 但在现实世界中已经无处不在。
无状态程序; 无副作用
无状态程序更容易testing。 现在广泛认可并且经常在工业中被利用。
并发; 对多核技术不断上升表示非常满意程序通常更短,在某些情况下更易读取生产力提高(例如:Erlang)
你正在合并并行和并行。
使用通信顺序进程(CSP)可以有效地完成并发。 CSP中的代码可以改变它的本地状态,但是在它们之间发送的消息应该永远是不可变的。
纯粹的函数式编程对于多核心起着非常不利的作用,因为它对caching不友好。 核心争夺共享内存,并行程序不能扩展。
为什么使用function语言编写程序的公司仍然如此“罕见”?
Scala通常被认为是一种function性的语言,但它不像C#那样是当今世界上最stream行的语言之一。
为什么在研究函数式编程的优点时,我们还在使用命令式编程语言呢?
纯函数式编程有很多严重的缺点,所以我们使用Lisp,Scheme,SML,OCaml,Scala和C#等不纯的函数式语言。
当我想到function编程可能会给我的项目带来什么时,我总是被带到了同样的思路:
-
为了获得function性编程的全部优点,你需要懒惰。 是的,有严格的function语言,但function编程的真正好处在严格的代码中不会发光。 例如,在Haskell中,很容易在列表上创build一系列惰性操作,并将它们连接起来并将它们应用到列表中。 例如。
op1 $ op2 $ op3 $ op4 $ someList
。 我知道这并不是要build立整个列表,而是在内部,我将得到一个很好的循环,一次一个地遍历元素。 这使您可以编写真正的模块化代码。 两个模块之间的接口可能涉及交付潜在的庞大的数据结构,但您不必将结构驻留。 -
但是当你懒惰的时候,很难推断内存的使用。 更改Haskell编译器标志经常会将algorithm使用的内存量从O(N)更改为O(1),有时除外。 当您的应用程序需要最大限度地利用所有可用的内存时,这并不是真的可以接受,即使对于不需要全部内存的应用程序也不是很好。
两件事情:
- 不pipe技术有多好,这都需要时间。 FP背后的想法是大约70岁。 但是它在软件工程(在战略上,在工业上)的主stream使用可能还不到10年。 要求开发者采用种族的新思维方式是可能的,但只是需要时间(多年,多年)。 例如,OOP在20世纪80年代初确实得到了主stream使用。 然而,直到二十世纪九十年代末,它才得到了hibernate。
- 你需要人们面对技术的力量,才会面临巨大的挑战 。 目前,人们使用的工具并不是不能使用并行性,而且工作起来还行。 当不使用并行的应用程序变得难以忍受时, 那么很多人将被迫使用并行工具,而FP可能会大受欢迎。 这也可能适用于FP的其他优势。