在我作为教练和培训师的日常工作中,越来越多的烦恼就是我所说的 FPF,即“函数式编程狂热”。通常,它源自那些在过去几年中最近发现 FP 并且尚未意识到这一点的人——就像 1940 年代以来的所有编程创新一样——它实际上并没有为我们解决所有问题。
抛开人们普遍持有的看法,即函数式程序可能相当不容易理解,即使对于有经验的 FP-ers,(当你意识到试图理解程序代码是程序员至少花费我们一半时间的时候,这是一个不小的考虑),有副作用的问题。
更具体地说,人们一直告诉我函数式程序没有。这显然是不正确的:一个没有副作用的程序是一个对我们没有任何用处的程序。在某处,不知何故,数据必须改变。尝试编写一个没有副作用的文字处理器。
FP 通过限制和本地化副作用帮助我们编写更可靠的代码——特别是更可靠的并发代码。但前提是你做对了。
编写充满并发错误的函数式程序是完全有可能的,事实上,这就是我们所说的许多团队正在做的事情。
但是,如果说函数是“干净的”——没有副作用,怎么会这样呢?好吧,从一个功能传递到下一个功能的银行账户余额可能确实是原始余额的副本(副本的副本),但从外部用户的角度来看,无论当前余额是多少,都是余额(它已经改变了。)
一旦我们坚持更改(例如,通过将其写入数据库,或通过事务内存,或者我们正在处理共享数据),行为就完成了。事实上:副作用。
Haskell、Clojure 和其他听起来像“Camel”的语言不会为我们进行并发思考。如果联名账户持有人 A 在尝试使用借记卡之前检查了他们的余额,但联名账户持有人 B 在 A 之前使用了他们的借记卡,那么——你可能会惊讶地发现——这些语言没有用于协调联名账户的内置功能像这样的交易悖论。您必须从用户的角度考虑您的软件应该如何处理并发场景。
在非 FP 工作中,我们通过严格限制和本地化对共享数据的并发访问,寻求使并发系统更可靠,更好,并发。FP 只是将这个概念嵌入到语言本身中,使之更容易、更可靠。
正如工作流框架不会决定您的工作流中应该发生什么一样,函数式程序也不会决定您的应用程序应该如何处理副作用。他们能做的最好的事情就是给你工具来实现你所做的决定。
然而,我所看到的(这是十年前我们都在 Great Workflow Ju Ju In The Sky 面前拜倒时的情况)是团队错误地依赖技术,相信通过某种魔法它将为他们处理这些场景。但是,就像所有的计算机程序一样,它们只会完全按照我们的指示去做。