首页 文章

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

提问于
浏览 1800
197

我已经阅读了一些关于声明/函数编程(语言)的文章,尝试过Haskell以及自己编写的文本 . 从我所看到的,函数式编程比传统的命令式风格有几个优点:

  • 无国籍计划;无副作用

  • 并发;随着多核技术的发展,它发挥得非常好

  • 程序通常较短,在某些情况下更容易阅读

  • 生产环境 力提高(例如:Erlang)

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

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

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

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

11 回答

  • 530

    No Perceived Need

    我记得我的老Boss Rick Cline 's response when I showed him a copy of John Backus'图灵奖演讲题为“可以从冯·诺依曼风格中解放出来的节目”吗?

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

  • 38

    Masterminds of Programming: Conversations with the Creators of Major Programming Languages

    [Haskell]为什么你认为没有函数式编程语言进入主流?约翰休斯:营销不佳!我不是指宣传;我们已经有了很多 . 我的意思是仔细选择一个目标市场利基来支配,然后坚定地努力使功能性编程成为解决这个利基的最有效方式 . 在快乐的日子里80年代,我们认为函数式编程对所有事情都有好处 - 但是将新技术称为“对一切都有好处”就像称之为“特别好无所求” . 该品牌应该是什么?这是John Launchbury在他在ICFP的邀请演讲中非常清楚地描述的一个问题 . 当他们的品牌是“功能语言软件”时,Galois Connections几乎陷入困境,但他们因为专注于“高保证软件”而不断壮大 . 许多人不知道技术创新是如何发生的,并期望更好的技术本身就会成为主导(“更好的捕鼠器”效应),但世界并不是那样 .

  • 27

    因为所有这些优点也是缺点 .

    无国籍项目;无副作用

    真实世界的程序都是关于副作用和变异的 . 当用户按下按钮时,因为他们想要发生某些事情 . 当他们输入某些内容时,他们希望该状态替换曾经存在的状态 . 当会计师Jane Smith结婚并将她的名字改为Jane Jones时,支持打印她的薪水的业务流程的数据库最好是处理那种突变 . 当你向外星人发射机关枪时,大多数人并没有在精神上模仿那个具有较少生命值的新外星人的建造;他们将其模型化为现有外星人属性的变异 .

    当编程语言概念从根本上反对被建模的域时,很难证明使用该语言是正确的 .

    并发;随着多核技术的发展,它发挥得非常好

    问题只是被推开了 . 使用不可变数据结构,您可以以可能使用陈旧数据为代价来获得廉价的线程安全性 . 使用可变数据结构,您可以始终处理新数据,但必须编写复杂的逻辑以保持数据的一致性 . 它并不像其中一个明显优于另一个 .

    程序通常较短,在某些情况下更容易阅读

    除非它们更长且更难阅读 . 学习如何阅读以功能风格编写的程序是一项艰巨的任务;人们似乎更善于将程序视为一系列要遵循的步骤,比如一个食谱,而不是作为一系列计算来实施 .

    生产环境 力提高(例如:Erlang)

    为了证明招聘那些知道如何以功能方式编程的程序员的大量费用, 生产环境 力必须上升很多 .

    记住,你不想丢掉一个工作系统;大多数程序员不是从头开始构建新系统,而是维护现有系统,其中大部分都是用非功能语言构建的 . 想象一下,试图向股东证明这一点 . 为什么要废弃现有的工作薪资系统,以数百万美元的价格建造一个新工资? “因为功能编程很棒”不太可能令股东高兴 .

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

    功能编程也很老 . 我不知道这个概念的年龄是如何相关的 .

    别误会我的意思 . 我喜欢函数式编程,我加入了这个团队,因为我想帮助将函数式编程的概念引入C#,我认为以不可变的风格编程是未来的方式 . 但是,功能风格的编程需要付出巨大的代价才能实现它的本质:向更具功能性的风格转变,而不是批判性地接受Haskell的纯洁与美丽以及放弃C语言 .

    我以构建编译器为生,我们绝对拥抱下一代编译器工具的功能风格 . 那是因为函数式编程从根本上说是我们遇到的各种问题的良好匹配 . 我们的问题都是关于获取原始信息 - 字符串和元数据 - 并将它们转换为不同的字符串和元数据 . 在发生突变的情况下,就像有人在IDE中输入一样,问题空间本身就适用于功能性技术,例如逐步重建仅更改树的部分 . 许多域没有这些很好的属性,使它们显然适合功能样式 .

  • 26

    两件事情:

    • It just takes time no matter how good a technology is. FP背后的想法已有70年历史 . 但它在软件工程(在战壕,工业中)的主流使用可能不到10年 . 要求开发人员采用种族新思维模式是可能的,但这需要时间(很多年) . 例如,OOP确实在1980年初的主流使用's. However, it did not gain dorminance until the late 1990' .

    • You need people to be forced to face a technology's strength before it hits it big . 目前,人们正在使用不能利用并行性的工具,而且工作正常 . 当不使用并行性的应用变得难以忍受时;然后很多人将被迫使用并行工具,FP可能会大受欢迎 . 这也可能适用于FP的其他优势 .

  • 21

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

    功能对于某些事情更好,对其他事情更糟,因此它永远不会“接管” . 但它在现实世界中已经无处不在 .

    无国籍项目;无副作用

    无状态程序更容易测试 . 现在,这已被广泛认可并经常在工业中被利用 .

    并发;通过不断发展的多核技术发挥得非常好程序通常更短,在某些情况下更容易阅读 生产环境 力提高(例如:Erlang)

    你在混淆并发和并行 .

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

    纯函数式编程在多核中的表现非常糟糕,因为它对缓存不友好 . 核心最终争用共享内存,并行程序无法扩展 .

    为什么公司使用或用函数式语言编写的程序仍然“罕见”?

    Scala通常被认为是一种功能语言,但它并不比C#更具功能性,C#是当今世界上最流行的语言之一 .

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

    纯功能编程有很多严重的缺点,所以我们使用不纯的函数语言,如Lisp,Scheme,SML,OCaml,Scala和C# .

  • 15

    当我想到函数式编程可能会给我的工作项目带来什么时,我总是引出同样的思路:

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

    • 但是当你有懒惰时,很难推断内存使用情况 . 更改Haskell编译器标志经常会将算法使用的内存量从O(N)更改为O(1),有时则不会 . 当您的应用程序需要最大限度地利用所有可用内存时,这是不可接受的,即使对于不需要所有内存的应用程序也不是很好 .

  • 14

    你已经得到了足够多的答案,我只提到了一些我还没有提到的东西 .

    首先,(在我看来)最重要的是,程序语言从它们的共同程度中受益匪浅 . 举一个例子,几乎任何几乎可以在任何程度上了解几乎任何主流程序(或OO)语言的人都可以很好地阅读其他大部分语言 . 我主动避免使用Java,C#,Cobol,Fortran或Basic(仅举几个例子),但可以很好地阅读它们中的任何一个 - 实际上,就像每天使用它们的人一样 .

    在功能方面,这不太真实 . 举个例子,我也可以合理地编写Scheme,但是's of little use in reading Ocaml or Haskell (for only a couple of examples). Even within a single family (e.g., Scheme vs., Common Lisp) familiarity with one doesn't似乎可以很好地转换到另一个 .

    功能代码更具可读性的说法仅在狭窄的条件下才是真实的 . 对于那些对语言非常熟悉的人来说,可读性确实很好 - 但对于其他人来说,它往往是旁边的不存在的 . 更糟糕的是,虽然程序语言的差异主要是语法,因此相对容易学习,但功能语言的差异往往更为基础,因此需要大量的学习才能真正理解(例如,了解Lisp对理解Monads没什么帮助) .

    另一个要点是函数式程序比程序性程序更短的想法通常更多地基于语法而不是语义 . 用Haskell编写的程序(例如)通常很短,但它的功能只是其中很小的一部分 . 如果仅仅是Haskell具有相对简洁的语法,那就太多了 .

    很少有纯粹的函数式语言可以与APL很好地竞争简洁的源代码(但是,公平地说,APL也支持创建更高级别的函数,因此与其他情况一样,这并没有太大差异) . 相反,Ada和C(仅用于几个示例)在完成给定任务所需的操作数量方面可以非常有竞争力,但语法(至少通常)更加冗长 .

  • 11

    股票的答案是既不会也不应该取代另一个 - 它们是具有不同优缺点的不同工具,哪种方法的优势取决于项目和其他“软”问题,如可用的人才库 .

    我认为,当选择函数式编程而不是其他样式时,由多核引起的并发性增长将增加(全局开发项目集)的百分比,这是正确的 .

    我认为这在今天很少见,因为今天的大多数专业人才库对于命令式和面向对象技术最为满意 . 例如,我不止一次选择Java作为商业项目的语言,因为它足够好,没有争议,而且我知道我永远不会用完可以编程(足够好)的人 .

  • 10

    不是吗?

    Smalltalk在当天是一个伟大的面向对象系统 . 为什么没有接管面向对象的编程?好吧,它有 . 它看起来不像Smalltalk . 主流语言在C,Java,C#等方面变得越来越像Smalltalk . 时尚和风格变化比任何东西都要慢,所以当OO成为主流时,我们通过将OO的部分粘贴到旧语言上来获得它,所以它看起来像C一样吞下去 .

    功能是一样的 . Haskell是一种很棒的函数式语言 . 但是,与20年前相比,我们现在拥有更多使用类C语法的主流程序员 . 因此它必须看起来像C.完成:查看任何LINQ表达式并告诉我它不起作用 .

  • 7

    尽管功能编程具有优势,但命令式和面向对象编程永远不会完全消失 .

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

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

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

  • 6

    我认为命令式语言更为普遍,因为这是更多人习惯的 . 函数式编程和命令式编程模型都不比其他模式更模糊或更具学术性 . 事实上,它们是互补的 .

    一张海报说,命令式代码比函数式编程代码更容易理解 . 只有当读者已经看到命令性代码时才会这样,特别是如果先前的示例是相同的"family"(例如,C / C,Perl,PHP和Java)的一部分 . 我不会声称任何命令式语言都是如此;比较Java和Forth,做一个极端的例子 .

    对于外行来说,所有编程语言都是难以理解的胡言乱语,除了可能是Hypertalk和SQL等冗长的语言 . (值得注意的是,SQL是一种声明性和/或功能性语言,并且非常受欢迎 . )

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

相关问题