理解什么是函数式编程,首先可以先对比一下传统的命令式编程;
例如:现在我们有这样一个数学表达式
3 + 1 * 2
使用命令式编程实现:
int mul_result = 1 * 2 ; int add_result = mul_result + 3 ;
使用函数式编程实现:
int result = add(multiply(1,2),3) 或 multiply(1,2).add(3);
命令式编程更关注的是任务的执行过程(图灵机的特点。一条写满数据的纸带,一条根据纸带内容运动的机器,机器每动一步都需要纸带上写着如何达到 ),而函数式编程关注的是数据映射(并非修改原来的数据状态,而是通过将数据映射到新的数据上,获得新的状态)
例子2:
如何翻转一个二叉树:
命令式编程:通过交换左右子树的节点即可实现
函数式编程:通过将左子树的节点映射到一个新的树的右子树节点,右子树同理。 —— 对于函数式编程,目的不是在于如何执行交换左右子树的节点,而是通过将左右子树重新映射到一个新的树上,到达不修改原有树结构,并且新的树对原有树也没有依赖关系(引用透明)
具备的特点与好处:
1. 函数也是一种数据类型,可以作为参数进行传递,或者赋予其他变量。
例如:
var fn = function(){ console.log(123); }[1,2,3].forEach(fn);
//输出 123 123 123
2. 使用“表单式”,而非“语句”
'表达式'(expression)是一个单纯的运算过程,总是有返回值;'语句'(statement)是执行某种操作,没有返回值。函数式编程要求,只使
用表达式,不使用语句。也就是说,每一步都是单纯的运算,而且都有返回值。
原因是函数式编程的开发动机,一开始就是为了处理运算(computation),不考虑系统的读写(I/O)。'语句'属于对系统的读写操作,所以就被排斥在外。
当然,实际应用中,不做I/O是不可能的。因此,编程过程中,函数式编程只要求把I/O限制到最小,不要有不必要的读写行为,保持计算过程的单纯性
3. 没有“副作用” —— 好处
所谓'副作用'(side effect),指的是函数内部与外部互动(最典型的情况,就是修改全局变量的值),产生运算以外的其他结果。
函数式编程强调没有'副作用',意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。函数不依赖外部,也不修改外部,故函数调用的结果不依赖调用的时间合位置,这样写出来的代码更容易进行推理,不易出错,更有利于单元测试。
4. 不修改状态 —— 好处
上一点已经提到,函数式编程只是返回新的值,不修改系统变量。因此,不修改变量,也是它的一个重要特点。
5. 引用透明 —— 好处
引用透明(Referential transparency),指的是函数的运行不依赖于外部变量或'状态',只依赖于输入的参数,任何时候只要参数相同,引用函数所得到的返回值总是相同的。
有了前面的第三点和第四点,这点是很显然的。其他类型的语言,函数的返回值往往与系统状态有关,不同的状态之下,返回值是不一样的。这就叫'引用不透明',很不利于观察和理解程序的行为。





































苏公安网备 32011402010933号