面向对象编程通过封装变化使得代码更易理解;
函数式编程通过最小化变化使得代码更易理解。
—Michael Feathers
作者利用Underscore、Lodash、Ramda、RxJS等代码库编写函数式代码示例,并与命令式代码示例进行比对,指出——函数式代码具有易推理、易测试的优点,函数式编程有利于驯服系统的复杂性。
有了curry、partial、compose,就能实践函数式编程了么?
我的答案是:不能。半年多前,我就看完了这本书,但我没办法将函数式编程真正应用于代码实践当中。函数式编程可以简单地归结为:分解与组合,但curry、partial、compose对于完成函数式编程是远远不够的。
尽管我对Scheme与Clojure的认知是肤浅的,但还是想谈谈——我对实践“函数式编程”的想法。作为Lisp的方言,所有的Scheme与Clojure代码都是由表达式组成的,每个表达式会求值产生一个值。前缀表示法简化了语法,括号使得“代码即数据”。表达式是函数式编程的基石,相较于其他语言中无值的控制语句,Lisp中的条件判断都是表达式。在JavaScript中使用三元运算符表示多路分支是多么的可怕啊,而且比较运算符不是过程,不符合point-free风格。
为了能用JavaScript进行函数式编程,我们需要借助外部的工具库来抽象过程和保证数据的不可变。Underscore、Lodash的传参方式不符合point-free风格,而Ramda是专门为函数式编程风格而设计。
真实世界中充满了状态,我们需要把不纯的部分从函数中抽离出来,将状态控制在局部。既然函数是值,那么也就能放入函子当中,使用IO Monad与外部资源进行交互。关于Monad的更多信息,可参考欧阳继超(本书译者之一)的《前端函数式攻城指南》。
jQuery所代表的命令式编程,已不足已应对当下前端系统所面对的复杂性。拥抱声明式编程,创建反应式应用。
文摘
函数式编程的目标是使用函数来抽象作用在数据上的控制流与操作,从而在系统中消除副作用并减少对状态的改变。
面向对象编程通过特定的行为将很多数据类型逻辑地连接在一起,函数式编程则关注如何在这些数据类型之上通过组合来连接各种操作。
方法链接通过对象的方法紧密连接,而管道以函数作为组件,将函数的输入和输出松散地连接在一起。但是,为了实现管道,被连接的函数必须在元数(arity)和类型上相互兼容。