如果这是一个模糊的问题,我深表歉意,但这里是:
在过去的几年里,函数式编程在软件工程社区中受到了很多关注。许多人已经开始使用 Scala 和 Haskell 等语言,并声称比其他编程语言和范例更成功。我的问题是:作为高性能计算/科学计算专家,我们应该对函数式编程感兴趣吗?我们应该参与这场小型革命吗?
SciComp 工作领域中函数式编程的优缺点是什么?
如果这是一个模糊的问题,我深表歉意,但这里是:
在过去的几年里,函数式编程在软件工程社区中受到了很多关注。许多人已经开始使用 Scala 和 Haskell 等语言,并声称比其他编程语言和范例更成功。我的问题是:作为高性能计算/科学计算专家,我们应该对函数式编程感兴趣吗?我们应该参与这场小型革命吗?
SciComp 工作领域中函数式编程的优缺点是什么?
我只做了一点函数式编程,所以对这个答案持保留态度。
我认为可以克服“缺点”部分中的许多反对意见。正如 Stack Exchange 网站上的一个常见讨论点,开发人员时间比执行时间更重要。即使函数式编程语言很慢,如果可以将性能关键部分委托给更快的过程语言,并且如果可以通过快速应用程序开发来证明生产力的提高,那么它们可能值得使用。这里值得注意的是,用纯 Python、纯 MATLAB 和纯 R 实现的程序比用 C、C++ 或 Fortran 实现这些相同的程序要慢得多。Python、MATLAB 和 R 等语言之所以受欢迎,正是因为它们以执行速度换取生产力,即便如此,Python 和 MATLAB 都具有在 C 或 C++ 中实现编译代码接口的工具,因此可以实现对性能至关重要的代码以快速执行。大多数语言都有一个到 C 的外部函数接口,这足以与计算科学家感兴趣的大多数库进行接口。
这一切都取决于你认为什么很酷。如果你是那种愿意打破常规的人,并且你愿意经历向人们宣传你想用函数式编程做任何事情的优点的艰难过程,我会说去吧. 我希望看到人们在计算科学中用函数式编程做一些很酷的事情,如果没有其他原因,只是为了证明所有反对者都是错误的(并且会有很多反对者)。如果您不是那种想与一群人打交道的人,他们会问您“到底为什么要使用函数式编程语言而不是(在此处插入他们最喜欢的过程式编程语言)?”,那么我不会不要打扰。
有一些函数式编程语言用于模拟密集型工作。量化交易公司 Jane Street 使用 OCaml 进行财务建模和执行其交易策略。OCaml 也用于 FFTW 生成库中使用的一些 C 代码。Liszt 是一种在斯坦福大学开发并在 Scala 中实现的特定领域语言,用于解决偏微分方程。函数式编程肯定在工业中使用(不一定在计算科学中);它是否会在计算科学中起飞还有待观察。
我可能对此有独特的看法,因为我是具有科学计算背景的 HPC 从业者以及函数式编程语言用户。我不想将 HPC 等同于科学计算,但存在相当大的交叉点,这就是我在回答这个问题时所采取的观点。
目前不太可能在 HPC 中采用函数式语言,主要是因为 HPC 用户和客户真正关心的是尽可能接近峰值性能。确实,当以函数式方式编写代码时,它自然会暴露出可以利用的并行性,但在 HPC 中这还不够。并行性只是实现高性能的难题之一,您还必须考虑广泛的微架构细节,这样做通常需要对代码执行进行非常细粒度的控制,这种控制在任何情况下都不可用我所知道的函数式语言。
也就是说,我寄予厚望,这可能会改变。我注意到一种趋势,即研究人员开始意识到许多这些微架构优化可以(在一定程度上)自动化。这孕育了一个源到源编译器技术的动物园,其中用户输入他们想要发生的计算的“规范”,编译器输出 C 或 Fortran 代码,这些代码通过有效的优化和并行性实现计算使用目标架构。顺便说一句,这是函数式语言非常适合做的事情:建模和分析编程语言。函数式语言的第一批主要采用者是编译器开发人员,这绝非偶然。除了一些值得注意的例外,我还没有看到这实际上已经站稳脚跟,但是想法就在那里,
我想在其他两个答案中添加一个方面。除了生态系统,函数式编程为并行执行(例如多线程或分布式计算)提供了绝佳机会。它固有的不变性特性使其适用于并行性,这对于命令式语言来说通常是一个真正的痛点。
由于近年来硬件性能的改进主要集中在向处理器添加内核而不是推动更高的频率,因此并行计算变得越来越流行(我打赌你们都知道这一点)。
Geoff 提到的另一件事是开发人员时间通常比执行时间更重要。我在一家构建计算密集型 SaaS 的公司工作,我们在开始时进行了初始性能测试,将 C++ 与 Java 进行比较。我们发现 C++ 比 Java 减少了大约 50% 的执行时间(这是针对计算几何,数字很可能会因应用程序而异),但由于开发人员时间的重要性,我们还是选择了 Java,并希望优化和未来的硬件性能改进将帮助我们将其推向市场。我可以自信地说,如果我们选择了其他方式,我们就不会继续营业了。
好的,但是 Java 不是一种函数式编程语言,所以你可能会问,它与任何东西有什么关系。好吧,后来随着我们聘请了更多函数式范式的支持者并偶然发现了并行化的需求,我们逐渐将系统的一部分迁移到了 Scala,它将函数式编程的积极方面与命令式的强大功能相结合,并与爪哇。它极大地帮助了我们提高系统性能,使我们的头痛最小化,并且当更多内核被塞进未来的处理器时,它可能会继续从硬件业务的进一步性能提升中获益。
请注意,我完全同意其他答案中提到的缺点,但我认为并行执行的便利性是如此强大,以至于不能不提及。
Geoff 已经很好地概述了我除了强调他的观点之一之外几乎没有补充的原因:生态系统。无论您是提倡函数式编程还是任何其他范式,您必须解决的一个重要问题是,有大量软件可以构建,您必须重新编写。例如用于线性代数的 MPI、PETSc 或 Trilinos,或任何有限元库——全部用 C 或 C++ 编写。系统中存在巨大的惯性,可能不是因为每个人都认为 C/C++ 实际上是编写计算软件的最佳语言,而是因为很多人花了数年的时间创造了一些有用的东西很多人。
我认为大多数计算人员都会同意尝试新的编程语言并评估它们对这个问题的适用性有很多价值。但这将是一段艰难而孤独的时期,因为您将无法产生与其他人正在做的事情竞争的结果。它还可能使您享有声誉,成为开始下一步转向不同编程范式的人。嘿,C++ 只用了大约 15 年就取代了 Fortran!