代码之家  ›  专栏  ›  技术社区  ›  Gordon Gustafson

函数式编程的缺陷/缺点[关闭]

  •  66
  • Gordon Gustafson  · 技术社区  · 15 年前

    你什么时候不想使用函数式编程?它不擅长什么?

    相关:

    9 回复  |  直到 7 年前
        1
  •  45
  •   Norman Ramsey    14 年前

    我很难想到函数式编程的许多缺点。再说一次,我是函数式编程国际会议的前任主席,所以你可以肯定地认为我是有偏见的。

    我认为主要的不利因素与孤立和进入壁垒有关。学习写作 好的 功能性程序意味着学会以不同的方式思考 要做好它需要大量的时间和精力的投入 . 没有老师很难学习。这些特性导致了一些缺点:

    • 一般来说,专家编写快速功能程序没有困难;事实上,在8和16个核心处理器上,一些性能最好的并行程序现在都写在 Haskell

    • 与开始Python或visualbasic的人相比,开始函数式编程的人更可能在实现预期的生产率提高之前放弃。只是在书籍和开发工具方面没有那么多的支持。

    • 可交谈的人少了。Stackoverflow就是一个很好的例子;相对来说很少有Haskell程序员定期访问这个站点(尽管这部分原因是Haskell程序员有自己的活跃论坛,这些论坛比Stackoverflow更古老、更完善)。

      同样,你不能很容易地和你的邻居交谈,因为函数编程概念比SimalTalk、Ruby和C++等语言背后的面向对象概念更难教和更难学习。而且,面向对象的社区已经花了好几年的时间来为他们所做的事情开发好的解释,而函数式编程社区似乎认为他们的东西显然很棒,不需要任何特殊的隐喻或词汇来解释。(他们错了。我还在等第一本好书呢 功能设计模式 .)

    • 懒惰的 函数式编程(适用于Haskell或Clean,但不适用于ML、Scheme或Clojure)是吗 很难预测评估的时间和空间成本 功能程序 -即使是专家也做不到。这个问题是范式的基础,不会消失。有很好的工具可以用来发现时间和空间行为 事后

        2
  •  29
  •   Chuck    15 年前

    函数式编程的一大缺点是,从理论上讲,它与硬件以及大多数命令式语言都不匹配。(这是其明显优势之一的另一面,即能够表达 什么 你想干完而不是 你想让电脑来做。)

    例如,函数式编程大量使用递归。这在纯lambda微积分中很好,因为数学的“堆栈”是无限的。当然,在真正的硬件上,堆栈是非常有限的。在大型数据集上天真地递归可能会使您的程序运行迅速。大多数函数式语言都对尾部递归进行了优化,这样就不会发生这种情况,但是使算法尾部递归可能会迫使您做一些相当糟糕的代码体操(例如,尾部递归映射函数创建一个向后列表或必须建立一个差异列表,因此,与非尾部递归版本相比,它必须做额外的工作才能以正确的顺序返回正常映射列表)。

    (感谢Jared Updike提出的差异列表建议。)

        3
  •  23
  •   Brian    15 年前

    如果您的语言不能提供很好的机制来通过程序检测状态/异常行为(例如,一元绑定的语法糖),那么任何涉及状态/异常的任务都将成为一件烦琐的事情。(即使有了这些糖,有些人可能会发现在FP中处理状态/异常更加困难。)

    函数式习语通常会导致大量的控制反转或惰性,这通常会对调试(使用调试器)产生负面影响。(由于不变性/引用透明性,FP不易出错,这在某种程度上抵消了这一点,这意味着您需要更少的调试次数。)

        4
  •  13
  •   Jared Updike    15 年前

    Philip Wadler为此写了一篇论文(名为为什么没有人使用函数式编程语言),并指出了阻止人们使用FP语言的实际缺陷:

    更新:访问ACM的用户无法访问旧链接:

        5
  •  8
  •   Ben Torell    15 年前

    除了速度或采用问题和解决一个更基本的问题外,我听说函数式编程很容易为现有数据类型添加新函数,但添加新数据类型“很难”。考虑:

    (用SMLnj书写。另外,请原谅这个有点做作的例子。)

    datatype Animal = Dog | Cat;
    
    fun happyNoise(Dog) = "pant pant"
      | happyNoise(Cat) = "purrrr";
    
    fun excitedNoise(Dog) = "bark!"
      | excitedNoise(Cat) = "meow!";
    

    fun angryNoise(Dog) = "grrrrrr"
      | angryNoise(Cat) = "hisssss";
    

    但是,如果我向Animal添加一个新类型,我必须遍历每个函数来添加对它的支持:

    datatype Animal = Dog | Cat | Chicken;
    
    fun happyNoise(Dog) = "pant pant"
      | happyNoise(Cat) = "purrrr"
      | happyNoise(Chicken) = "cluck cluck";
    
    fun excitedNoise(Dog) = "bark!"
      | excitedNoise(Cat) = "meow!"
      | excitedNoise(Chicken) = "cock-a-doodle-doo!";
    
    fun angryNoise(Dog) = "grrrrrr"
      | angryNoise(Cat) = "hisssss"
      | angryNoise(Chicken) = "squaaaawk!";
    

        6
  •  3
  •   Evan Carroll    15 年前

    我只是想讲一个趣闻轶事,因为我现在正在学习哈斯凯尔。我之所以学习Haskell,是因为将函数与动作分离的想法很吸引我,而且由于纯函数与非纯函数的隔离,隐式并行化背后有一些非常吸引人的理论。

    我已经学了三天的函数折叠课了。Fold似乎有一个非常简单的应用程序:获取一个列表并将其缩减为单个值。Haskell实现了 foldl foldr 为了这个。这两个函数有着完全不同的实现。有另一种实现 ,称为 foldl' . 除此之外,还有一个语法稍有不同的版本称为 foldr1 foldl1 不同的初始值。其中有一个相应的实现 foldl1' 对于 . 好像所有这些都不是令人兴奋的,功能 fold[lr].* redex ). 了解原因 福尔德 在无限列表上工作至少需要对lazybehavoir语言有一个适当的理解,并且需要对不是所有函数都会强制计算第二个参数的次要细节。对于那些在大学里从未见过这些函数的人来说,这些函数的在线图表令人困惑。没有 perldoc

    噢,fold不必将列表缩减为非列表类型的标量,列表的标识函数可以编写 foldr (:) [] [1,2,3,4]

    /我又回去看书了。

        7
  •  2
  •   Caleb    15 年前

    以下是我遇到的一些问题:

    1. 大多数人发现函数式编程很难理解。这意味着编写函数代码对你来说可能会更困难,而对于其他人来说几乎肯定更难掌握。
    2. 函数式编程语言通常比c语言慢。随着时间的推移,这个问题越来越少(因为计算机越来越快,编译器也越来越聪明)
    3. 缺少工具,尤其是调试工具。它绝对不像打开visualstudioforc#或eclipseforjava那么简单。
        8
  •  0
  •   Robert Harvey Isaac Blanco    14 年前

    撇开函数式编程具体实现的细节,我看到两个关键问题:

    1. 由于某些我从未真正理解的原因,函数式编程语言(或者它们的实现或社区?)他们更希望一切都用他们的语言。用其他语言编写的库的使用要少得多。如果其他人对某个复杂操作有特别好的实现,那么使用它而不是自己做更合理。我怀疑这在一定程度上是由于使用了复杂的运行时,使得处理外来代码(尤其是高效地执行)变得相当困难。我希望在这一点上被证明是错误的。

    我想这两者都是由于函数式编程的普遍缺乏实用性,这是由于函数式编程被编程研究人员比普通的编码人员使用得更为强烈。一个好的工具可以使专家完成伟大的事情,但是一个好的工具是一个能让普通人接近专家通常所能做的事情的工具,因为这是一个更困难的任务。