函数式编程有哪些好处?

111

你认为函数式编程的好处是什么?它们如何适用于今天的程序员?

函数式编程和面向对象编程之间最大的区别是什么?


6
布鲁布悖论。http://www.paulgraham.com/avg.html - missingfaktor
请查看 http://c2.com/cgi/wiki?AdvantagesOfFunctionalProgramming。 - EliuX
9个回答

87

函数式编程的风格是描述你想要的东西,而不是如何获得它。例如:不会通过创建带有迭代器变量并遍历数组完成每个单元格操作的for循环,而是说等价于“此标签指向对此数组版本,在所有元素上执行了此函数。”

函数式编程将更基本的编程思想移入了编译器,例如列表推导和缓存。

函数式编程最大的好处是简洁性,因为代码可以更加精简。函数式程序不会创建一个迭代器变量来成为循环的中心,因此这种和其他类型的开销都可以从您的代码中消除。

另一个主要的优点是并发性,因为函数式编程更容易实现,并且编译器正在处理大部分以前需要手动设置状态变量(如循环中的迭代器)的操作。

在单处理器的情况下,可以看到一些性能优势,具体取决于程序的编写方式,因为大多数函数式语言和扩展都支持惰性求值。在Haskell中,您可以说“此标签表示包含所有偶数的数组”。这样的数组是无限大的,但您可以随时请求该数组的第100,000个元素,而不必在数组初始化时知道您将需要的最大值是多少。该值只会在需要时计算,不再进一步计算。


14
我认为你的第一段更接近于描述像Prolog这样的陈述性关系编程,而不是函数式编程。 - McPherrinM
6
函数式语言是声明式的,而不是命令式的。 - Lie Ryan
2
似乎你正在混淆DP和IP,以及过程式编程和函数式编程。函数式编程通过强调函数组合来实现关注点分离,即将确定性计算的子计算之间的依赖关系分离。 - Shelby Moore III
2
@LieRyan 不正确。请查看我之前评论中的链接。 - Shelby Moore III
并发性是指具有多个线程可以相互交互的特性,这是必要条件。同时进行多个独立计算的过程称为“并行处理”。详见http://en.wikipedia.org/wiki/Concurrency_(computer_science)。 - Lambda Fairy

33

最大的好处是不同于你已经熟悉的。选择像Scheme这样的语言并学习如何用它解决问题,你将成为在已知语言中更加优秀的程序员。就像学习第二门人类语言一样。你可能会认为其他语言基本上只是你自己语言的变体,因为你没有可比性。接触其他语言,尤其是那些与你已经了解的内容不相关的语言,是有益的。


32
学习它的好处,而不是范式本身的好处。 - Moe
2
但它们真的是分开的吗?从原问题提出者的角度来看,我认为不是 - 他们很可能正在寻求学习函数式语言所需付出的努力所带来的总体收益。 - Kendall Helmstetter Gelner
3
学习函数式编程的好处在于,它可以渗透到你的其他面向对象编程工作中,并有助于简化开发过程。你可以通过“从输入计算输出”和“组合这两个计算新数据的函数”来解决问题,而不是通过“等待——那边的某个共享变量是什么状态?”和“我是否按正确的顺序执行了这些程序?”的方式。值得注意的是,你可以在 Python、C#、C++、Java 等语言中获得这些好处(理解函数式编程范式)。 - Jared Updike

14

为什么函数式编程很重要
http://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf

摘要

随着软件变得越来越复杂,良好的结构变得越来越重要。良好结构化的软件易于编写和调试,并提供了一组模块,可以在未来降低编程成本。

在本文中,我们展示了函数式语言的两个特性,即高阶函数和惰性求值,可以显著地促进模块化。举例来说,我们操纵列表和树、编写多个数值算法并实现了α-β启发式算法(一种用于游戏程序的人工智能算法)。我们得出结论,由于模块化是成功编程的关键,函数式编程为软件开发提供了重要的优势。


12

因此,一个很好的起点是尝试理解在命令式语言中不可能但在函数式语言中可能实现的一些事情。

如果你谈论可计算性,当然函数式编程和命令式编程之间没有任何互斥的部分(或者相反)。

不同编程范型的重点不是使以前不可能的事情变得可能,而是使以前难以完成的事情更容易。

函数式编程旨在让你更轻松地编写简洁、无错且可并行化的程序。


8

我认为需要函数式编程最实用的例子就是并发 - 函数式程序天然地线程安全,鉴于多核硬件的兴起,这是至关重要的。

函数式编程还增加了模块化 - 你经常会在命令式编程中看到太长的方法/函数 - 你几乎不会看到超过几行的函数。由于一切都是解耦的 - 可重用性大大提高,并且单元测试非常非常容易。


6

不必纠结于选择其中一种方式:使用类似C#3.0的语言可以混合使用各自最优秀的元素。面向对象可以用于类级别及以上的大规模结构,函数式风格可用于方法级别的小规模结构。

使用函数式风格可以编写清晰表达意图的代码,而不会与控制流语句等混淆。由于具有无副作用编程等原则,因此更容易推理代码并检查其正确性。


4
一旦程序增长,我们的词汇表中的命令数量就会变得太多,使用起来非常困难。这就是面向对象编程使我们生活更轻松的地方,因为它允许我们以更好的方式组织我们的命令。我们可以将涉及客户的所有命令与某个客户实体(类)相关联,从而使描述更加清晰。但是,程序仍然是一系列命令,指定它应该如何进行。
函数式编程提供了完全不同的扩展词汇的方法。不仅限于添加新的原始命令;我们还可以添加新的控制结构-指定如何将命令组合在一起创建程序的原语。在命令式语言中,我们能够按顺序或使用有限的内置结构(例如循环)组合命令,但是如果查看典型程序,您仍会看到许多重复的结构;以常见的方式组合命令。

2
不要把函数式编程看作是一种“必需品”。相反,把它看作是另一种编程技术,就像面向对象编程、模板、汇编语言等一样,当你学习它们(如果你学习它们的话),会完全改变你的思维方式。最终,学习函数式编程将使你成为更好的程序员。

0

如果你还不了解函数式编程,学习它将为你提供更多解决问题的方法。

函数式编程是一种简单的泛化方式,将函数提升为一等值,而面向对象编程则用于大规模代码结构。然而,在某些重叠的地方,面向对象设计模式可以直接使用一等函数来表示,而且更加简洁。

许多语言都提供了函数式编程和面向对象编程,包括OCaml、C# 3.0和F#。

祝好, Jon Harrop。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接