Functional programming 副作用是好事吗?

Functional programming 副作用是好事吗?,functional-programming,procedural-programming,side-effects,Functional Programming,Procedural Programming,Side Effects,我觉得这个词有点贬义。因此,我对维基百科中的两句话感到震惊: 命令式编程以 利用副作用来制造 程序功能。功能的 反过来,编程又以其独特的功能而闻名 尽量减少副作用 因为我有点数学偏见,后者听起来很棒。副作用的理由是什么?它们是指失去控制还是接受不确定性?它们是好东西吗?首先,用副作用编程要容易得多,也更直观。函数式编程对于很多人来说是很难理解的——如果你找到一个曾经在Ocaml上过课的人,你可能会听到各种各样的关于人们理解它的失败的故事。如果没有人能真正理解,那么拥有设计精美、无副作用的功能代码

我觉得这个词有点贬义。因此,我对维基百科中的两句话感到震惊:

命令式编程以 利用副作用来制造 程序功能。功能的 反过来,编程又以其独特的功能而闻名 尽量减少副作用


因为我有点数学偏见,后者听起来很棒。副作用的理由是什么?它们是指失去控制还是接受不确定性?它们是好东西吗?

首先,用副作用编程要容易得多,也更直观。函数式编程对于很多人来说是很难理解的——如果你找到一个曾经在Ocaml上过课的人,你可能会听到各种各样的关于人们理解它的失败的故事。如果没有人能真正理解,那么拥有设计精美、无副作用的功能代码又有什么好处呢?这使得雇佣人员来完成您的软件变得相当困难

这至少是争论的一个方面。有很多原因让很多人不得不学习函数式、无副作用的代码。想到了多线程。

Pro:

  • 最终,副作用是你想要实现的
  • 对于与外部世界交互的代码来说,副作用是很自然的
  • 它们使许多算法变得简单
  • 为了避免使用副作用,您需要通过递归实现循环,因此您的语言实现需要尾部调用优化
反对:

  • 纯代码很容易并行化
  • 副作用会使代码变得复杂
  • 纯代码更容易证明正确

例如Haskell,一开始它看起来很优雅,但后来你需要开始和外部世界玩,它不再那么有趣了。(Haskell将状态作为一个函数参数移动,并将其隐藏到称为monad的东西中,这使您能够以命令式的外观进行编写。)

在冯·诺依曼机器中,副作用是使机器工作的东西。本质上,无论您如何编写程序,它都需要做一些副作用才能工作(在低级别视图中)

没有副作用的编程意味着将副作用抽象出来,这样您就可以考虑一般问题,而不必担心机器的当前状态,并减少程序不同模块之间的依赖性(无论是过程、类还是其他)。通过这样做,您将使您的程序更加可重用(因为模块不依赖于特定状态工作)


因此,是的,无副作用的程序是一件好事,但副作用在某种程度上是不可避免的(因此它们不能被视为“坏”)。

没有副作用,你就无法做某些事情。一个例子是I/O,因为根据定义,使消息出现在屏幕上是一种副作用。这就是为什么函数式编程的目标是最小化副作用,而不是完全消除它们


撇开这一点不谈,通常情况下,最小化副作用与其他目标(如速度或内存效率)存在冲突。其他时候,你的问题已经有了一个概念模型,与变异状态的想法很好地吻合,与现有模型的斗争可能会浪费精力和精力。

对于大多数应用程序来说,副作用是必不可少的。 纯函数有很多优点。它们更容易考虑,因为你不必担心前置和后置条件。因为它们不改变状态,所以更容易并行化,这将随着处理器数量的增加而变得非常重要

副作用是不可避免的。无论何时,只要它们是比更复杂但更纯粹的解决方案更好的选择,就应该使用它们。纯函数也是如此。有时一个问题最好用功能解决方案来解决


这一切都是好的=)你应该根据你正在解决的问题使用不同的范例。

副作用是一种必要的邪恶,人们应该设法将其最小化/本地化

关于线程的其他评论说,无效果编程有时并不像<强>直觉> /强>,但我认为人们认为“直觉”主要是其先前经验的结果,并且大多数人的经验具有强烈的命令性偏倚。主流工具每天都在变得越来越实用,因为人们发现无效果编程导致的bug越来越少(尽管承认有时会出现新的/不同种类的bug),因为独立组件通过效果交互的可能性越来越小


几乎没有人提到性能,无效果编程的性能通常比有效性差,因为计算机是冯·诺依曼机器,设计用于效果(而不是设计用于lambdas)。现在我们正处于多核革命之中,这可能会改变游戏规则,因为人们发现他们需要利用核来获得性能,而并行化有时需要火箭科学家才能完全获得正确的效果,而在没有效果的情况下,很容易获得正确的效果。

没有副作用,您不能执行I/O操作;所以你不能做一个有用的应用程序。

我经常会看到一个问题,这迫使我花半个小时编辑一篇非常糟糕的维基百科文章。这篇文章现在只差一点。在与你的问题有关的部分,我写道:

在计算机科学中,如果一个函数或表达式除了产生一个值之外,还修改了某些状态,或者与调用函数或外部世界有可观察的交互作用,那么它就被称为具有副作用。例如,一个函数可能修改一个全局变量或静态变量,修改它的一个参数,引发一个e