为什么还没有接受函数式编程呢?

Why hasn't functional programming taken over yet?

我读过一些关于声明性/函数式编程(语言)的文章,尝试过haskell,也自己写过一篇。从我所见,函数式编程比经典的命令式编程有几个优点:

  • 无状态程序;无副作用
  • 并发性;对新兴的多核技术非常好
  • 程序通常更短,在某些情况下更容易阅读。
  • 生产力提高(例如:二郎)

  • 命令式编程是一种非常古老的范式(据我所知),可能不适合21世纪。

为什么公司使用或用功能语言编写的程序仍然如此"罕见"?

为什么,在研究函数式编程的优点时,我们仍然使用命令式编程语言?

也许在1990年还为时过早,但今天呢?


因为所有这些优点都是缺点。

Stateless programs; No side effects

现实世界中的程序都是关于副作用和变异的。当用户按下一个按钮时,是因为他们希望发生一些事情。当他们输入某些内容时,他们希望该状态替换曾经存在的任何状态。当会计界的简·史密斯结婚后,将自己的名字改为简·琼斯时,支持打印工资支票的业务流程的数据库最好都是关于处理这种变异的。当你向外星人发射机关枪时,大多数人不会在心理上将其建模为具有较少生命点的新外星人的构造;他们将其建模为现有外星人属性的突变。

当编程语言概念从根本上与被建模的领域相反时,很难证明使用该语言是合理的。

Concurrency; Plays extremely nice with the rising multi-core technology

这个问题只是推波助澜。对于不可变的数据结构,您可以以处理过时数据为代价,获得廉价的线程安全性。使用可变的数据结构,您可以随时处理新的数据,而不必编写复杂的逻辑来保持数据的一致性。这并不是说其中一个明显比另一个好。

Programs are usually shorter and in some cases easier to read

除了那些阅读时间更长、更难阅读的情况。学习如何阅读以功能性方式编写的程序是一项困难的技能;人们似乎更善于将程序设想为一系列要遵循的步骤,如一个食谱,而不是一系列要执行的计算。

Productivity goes up (example: Erlang)

为了证明雇佣那些知道如何以功能性方式编程的程序员的巨额开支是合理的,生产力必须提高很多。

记住,你不想抛弃一个工作的系统;大多数程序员不是从头开始构建新系统,而是维护现有的系统,其中大部分是用非功能语言构建的。想象一下,试图向股东证明这一点。你为什么要放弃现有的工作工资制度,以数百万美元的代价建立一个新的工资制度?因为功能编程太棒了"不太可能让股东高兴。

Imperative programming is a very old paradigm (as far as I know) and possibly not suitable for the 21th century

函数编程也很古老。我不知道这个概念的年龄是如何相关的。

别误会我。我喜欢函数式编程,我加入这个团队是因为我想帮助将概念从函数式编程引入C中,我认为以不变的方式编程是未来的发展方向。但是,以一种功能性的方式进行编程有着巨大的成本,这是不可能被简单地期望的。在几十年的时间里,向功能性更强的风格的转变将缓慢而逐渐地发生。而这将是:向一种更具功能性的风格转变,而不是大规模的拥抱哈斯克尔的纯洁和美丽以及放弃C++。

我以编译程序为生,我们肯定会接受下一代编译器工具的功能风格。这是因为函数式编程从根本上说是我们所面临的各种问题的良好匹配。我们的问题都是获取原始信息——字符串和元数据——并将它们转换为不同的字符串和元数据。在发生突变的情况下,就像有人在IDE中打字一样,问题空间本身就提供了一些功能性技术,比如只增量地重建树中发生变化的部分。许多域没有这些很好的属性,使它们明显适合于功能样式。


编程大师:与主要编程语言创建者的对话

[Haskell]

Why do you think no functional programming language has entered the mainstream?

John Hughes: Poor marketing! I don't mean propaganda; we've had plenty of that. I mean a careful choice of a target market niche to dominate, followed by a determined effort to make functional programming by far the most effective way to address that niche. In the happy days of the 80s, we thought functional programming was good for everything - but calling new technology"good for everything" is the same as calling it"particularly good at nothing". What's the brand supposed to be? This is a problem that John Launchbury described very clearly in his invited talk at ICFP. Galois Connections nearly went under when their brand was"software in functional languages," but they've gone from strength to strength since focusing on"high-assurance software."

Many people have no idea how technological innovation happens, and expect that better technology will simply become dominant all by itself (the"better mousetrap" effect), but the world's just not like that.


股票的答案是,两者都不会或应该取代另一个-它们是不同的工具,有不同的利弊,哪种方法具有优势将取决于项目和其他"软"问题,如可用人才库。

我认为您是对的,当选择函数式编程而不是其他样式时,由于多核而导致的并发性增长将增加(全局开发项目集的)百分比。

我认为这在今天是罕见的,因为今天的大多数专业人才库最适合使用命令式和面向对象的技术。例如,我不止一次选择Java作为一个商业项目的语言,因为它是足够好的,没有争议,我知道我永远不会耗尽那些能在程序中编程的人。


尽管函数式编程有很多优点,但命令式编程和面向对象编程永远不会完全消失。

命令式和面向对象编程是对问题及其解决方案的逐步描述。因此,它更容易理解。函数式编程可能有点模糊。

最终,一个有用的程序总是会有副作用(比如向用户提供实际的输出以供消费),所以最纯粹的函数语言仍然需要一种方法来不时地进入命令世界。

当前最先进的技术是命令式语言(如C)从功能世界(如lambda语句)借用功能,反之亦然。


不是吗?

smalltalk在当时是一个面向对象的系统。为什么没有面向对象编程接管?嗯,它有。它看起来不像是小型谈话。主流语言越来越像Sc++、爪哇、C等。Simple和Stand比任何东西都要慢,所以当OO走向主流时,我们通过将OO的一些部分粘贴到旧的语言中得到它,所以它看起来足够像C吞下。

功能也是一样的。哈斯克尔是一种伟大的功能语言。但是我们现在使用C类语法的主流程序员比20年前还要多。所以它必须看起来像c.done:看看任何linq表达式,告诉我它不起作用。


我相信命令式语言更普遍,因为这正是越来越多的人习惯的。函数式编程和命令式编程模型都不比另一种更为模糊或学术化。事实上,它们是互补的。

一位海报上说,命令式代码比函数式编程代码更容易理解。只有当读者已经看到命令式代码时,这才是正确的,特别是如果前面的示例是同一个"家庭"的一部分(例如,C/C++、Perl、PHP和Java)。我不会声称这是真的任何命令语言;比较Java和FEXT,做一个极端的例子。

对于一个外行来说,所有的编程语言都是不可分辨的胡言乱语,除了诸如hypertalk和sql之类的冗长语言。(注意,SQL是一种声明性和/或功能性语言,并且非常流行。)

如果我们从一开始就接受过Lisp-Y或Haskell-Y语言的培训,我们都会认为函数式编程语言是完全正常的。


你已经得到了足够的答案,我只会提到一些我还没有看到提到的事情。

首先,在我看来,程序语言从它们的共性程度中受益匪浅。例如,几乎任何一个对主流程序(或OO)语言几乎有任何了解的人都能很好地阅读其他大多数语言。我积极避免在爪哇工作,例如C、COBOL、FORTRAN或BASIC(仅举几个例子),但是可以很好地阅读它们中的任何一个——几乎和那些每天使用它们的人一样。

在功能性方面,这就不那么正确了。例如,我也可以非常合理地编写方案,但在读取ocaml或haskell(仅用于几个示例)时,这几乎没有用处。即使是在一个单一的家庭中(例如,Scheme与Common Lisp),熟悉其中一个似乎也不能很好地将其转化为另一个。

功能代码可读性更强的说法往往只有在很窄的条件范围内才是正确的。对于非常熟悉该语言的人来说,可读性确实非常好——但对于其他人来说,可读性往往是仅次于不存在的。更糟的是,虽然程序语言的差异很大程度上是由语法决定的,因此相对容易学习,但功能语言的差异往往更为根本,因此需要大量的研究才能真正理解(例如,了解Lisp对理解Monad几乎没有帮助)。

另一个主要观点是,功能程序比过程程序短的观点通常更多地基于语法而不是语义。用haskell编写的程序(例如)通常很短,但其功能性只是其中的一小部分。如果只是haskell有一个相对简洁的语法,那就太多了。

很少有纯函数语言能在简洁的源代码方面与APL进行很好的竞争(不过,公平地说,APL也支持创建更高级别的函数,所以这与其他一些情况的差异不大)。相反,艾达和C++(对于几个例子)在完成给定任务所需的操作数方面是相当有竞争性的,但是语法至少通常是冗长的。


没有感知到的需求

我记得我的老老板里克·克林(RickCline)在给他看约翰·巴克斯(JohnBackus)的图灵奖(Turing Award)演讲时的回答,演讲题目是"编程能从冯·诺依曼风格中解放出来吗?"

他的回答是:"也许我们中的一些人不想从冯·诺依曼的风格中解放出来!"


Why hasn't functional programming taken over yet?

功能性对某些事物更好,对其他事物更差,因此它永远不会"接管"。但它在现实世界中已经无处不在。

Stateless programs; No side effects

无状态程序更容易测试。这一点现在得到了广泛的重视,并经常在工业上得到利用。

Concurrency; Plays extremely nice with the rising multi-core technology
Programs are usually shorter and in some cases easier to read
Productivity goes up (example: Erlang)

你把并行和并行混为一谈。

使用通信顺序进程(CSP)可以有效地实现并发性。CSP中的代码可以改变其本地状态,但它们之间发送的消息应该始终是不可变的。

纯函数式编程在多核环境下非常糟糕,因为它缓存不友好。核心最终会争夺共享内存,而并行程序无法扩展。

Why are companies using or programs written in functional languages still so"rare"?

scala通常被认为是一种功能性语言,但它的功能性并不比C强,后者是当今世界上最流行的语言之一。

Why, when looking at the advantages of functional programming, are we still using imperative programming languages?

纯函数编程有很多严重的缺点,所以我们使用一些不纯的函数语言,如lisp、scheme、sml、ocaml、scala和c。


当我想到函数式编程会给我工作中的项目带来什么时,我总是沿着同样的思路走下去:

  • 为了充分利用函数式编程的优点,您需要懒惰。是的,虽然有严格的函数语言,但是函数编程的真正好处在严格的代码中并不明显。例如,在haskell中,很容易在一个列表上创建一系列惰性操作,并将它们连接起来并应用到一个列表中。如op1 $ op2 $ op3 $ op4 $ someList。我知道它不会构建整个列表,在内部我只会得到一个很好的循环,一次一个循环遍历元素。这允许您编写真正的模块化代码。两个模块之间的接口可能涉及到潜在的大量数据结构的移交,但是您不必让结构驻留。

  • 但是当你有懒惰的时候,就很难解释内存的使用。更改haskell编译器标志经常会将算法使用的内存量从o(n)更改为o(1),但有时不这样做。当您的应用程序需要最大限度地利用所有可用内存时,这是不可接受的,即使对于不需要所有内存的应用程序也不太好。


  • 两件事:

  • 不管技术有多好,都需要时间。《金融政策》背后的思想大约有70年的历史。但它在软件工程中(在工业领域)的主流应用可能不到10年。要求开发者采用种族主义的新思维方式是可能的,但这需要时间(很多,很多年)。例如,OOP在20世纪80年代早期确实得到了主流使用,但直到20世纪90年代末才获得宿舍贷款。
  • 你需要人们在技术发展壮大之前被迫面对它的力量。目前,人们使用的工具并没有利用并行性,而且工作正常。当不使用并行的应用程序变得难以忍受的缓慢时,许多人将被迫使用并行工具,而FP可能会迅速流行起来。这也适用于FP的其他优势。