JavaScript轻量级函数式编程

前言

单子是自函子范畴上的一个半幺群。

看到这句话是不是感觉一脸懵逼?别担心,其实我也是。这些单词仅仅在创造了它们的函数式编程中有点意义而已,它们对我们之中的绝大部分人而言都是毫无意义的。

这本书并不会告诉你这些词语是什么意思。但如果这正是你需要的,那请你继续寻找吧,事实上已经有很多在教导函数式编程方面非常出色的书籍了。这些词语具有非常重要的意义,如果你想要正式的深入学习函数式编程,你绝对是想要熟悉它们的。

但是这本书将会以不同的方式来讲解这个主题。我将会从头开始,从最基本的概念开始,比起其他大多数方法,这样做将只会使用很少特殊的或者是非直观描述的术语。我们将会尝试对每个原理采取切实可行的练习方式,而不是从纯粹的学术角度来看待它。毫无疑问的,这也是会有不少术语的,但是我们会小心谨慎的介绍它们,并解释它们为什么重要。

可悲的是,我并不是函数式编程俱乐部的成员,我从来没有正式接受过任何有关函数式编程的教导。虽然我有CS的学术背景,并且擅长于数学,但是数学符号并不是我大脑理解的编程。我从未写过一行Scheme Clojure或者是Haskell。我也并不是一个古典的Lisp编程者。

我曾参加过无数关于函数式编程的会议,每个人在最后总是在绝望中带着些许希望——这一次,我一定能完全搞懂函数式编程到底是在讲什么。然后,每一次我都是失望而归,这些术语和概念充斥在我的脑海中,我不知道我到底学到了什么。而且在很长的时间内,我都不知道这些东西是什么。

渐渐的,在这些各种各样的概念术语之中,我梳理出了一些重要的概念,它们似乎都是被正常的函数式编程者们普通地使用着。我慢慢的在实践和练习中学习它们,而不是纯粹的在学术上学习它们的意义。你有过这样的经历吗?你知道某件事情很久了,但是直到最近你才知道这件事情原来有个专门的名字,而你却从来不知道!

也许你和我很相似;我听说过“大数据”这样的行业部门中有“map-reduce”这样的术语,但是我对它们是什么并不怎么关心。最终,我明白了map(..)到底函数做了什么,在那之前很长一段时间,我并不知道列表操作是函数式编程编程的基础,以及是什么使得它们如此重要。我在很早之前就知道了什么是map操作,但是,我现在才知道它原来被称作map(..)

最终,我开始把我所理解的这些东西都收集到了我现在所说的“轻量级函数式编程”(FLP)之中。

目标

但是,为什么学习函数式编程如此重要,甚至只是轻量级的形式?

最近几年我变得近乎宗教信仰似的相信某些事情。我相信着编程从根本上来说,核心应该是人,而不是代码本身。我相信代码首先应该是人类沟通的手段之一,只是它还有着能操作计算机工作的副作用而已(我自己都笑了)。

按照我自己的理解,我认为函数式编程的核心作用就是,它是由各种众所周知的、容易理解的代码片段组合而成,这样能够让你的代码尽量避免错误,那种让代码变得难以理解的错误。在这种观点下,FP——唔,不对,是FLP!——可能是任何开发人员都可以获得的最重要的工具集合之一。

单子有一个诅咒……那就是,一旦你学会了它……你就失去了向别人解释它的能力。
Douglas Crockford 2012 “Monads and Gonads”
https://www.youtube.com/watch?v=dkZFtimgAcM

我希望这本书“也许”能够打破这种诅咒,虽然我们直到书最后的附录中我们才会提到它。

函数式编程者们经常断言道,函数式编程的真正价值在于你必须百分百的使用它:这是个非黑即白的命题。也就是说,如果你只在程序的部分中使用函数式编程,而其他部分没有使用函数式编程,那么整个程序就会被非函数式编程的东西污染,因此这样来使用函数式编程并不值得。

我会毫不含糊的说:我认为这样的绝对主义是错误的!我觉得这东西真的是很愚蠢,因为这暗示了这本书只有在我使用完美的语法以及生动的语言才是好的;假如我犯下了任何错误,这就会降低整本书的质量。真是废话。

我写得越是清楚越是一致,这本书的经验就越适合你。但我并不是个百分之百完美的作者,有些部分我会比别人写得更好,有些部分则还有改进的余地,但是这些并不会影响整本书的质量。

代码也是一样的,你可以将这些原理应用到代码之中,使用的越多你的代码就会越好。如果你在25%的时间中使用它们,你会得到一些益处;你用了80%的事件,你会得到更多的益处。

也许有一些例外,但我并不认为你会在这本书中找到许多绝对之物。相反,我们将会谈论愿望、目标、以及原则,我们将会讨论平衡和实用主义以及如何权衡取舍。

欢迎来到这个关于函数式编程最有用以及最实用的基础教程之旅。我们一起来认真学习吧!