函数式编程
目前程序届分为两类编程:命令式和函数式,面向对象编程本身也是命令式编程的范畴.
函数式编程有两个最基本的运算:合成和柯里化。
合成
如下:compose包含函数f,g合成
const compose = function (f, g) {
return function (x) {
return f(g(x));
};
}
柯里化
把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数
f(x)和g(x)合成为f(g(x))前提,就是f和g都只能接受一个参数。
// 柯里化之前
function add(x, y) {
return x + y;
}
add(1, 2) // 3
// 柯里化之后
function addX(y) {
return function (x) {
return x + y;
};
}
addX(2)(1) // 3
3个条件
编程函数,需要满足下面3个条件,即可转换成纯数学函数。
每个函数必须包含输入参数(作为自变量)
每个函数必须有返回值(作为因变量)
无论何时,给定参数调用函数时,返回值必须一致。
根据上面的条件可以归纳出下面的扩展要求:
高阶函数
高阶函数实际上就是函数的函数,它是所有函数式语言的性质。
递归、尾调用和尾递归
由于变量不可变,纯函数编程语言里面无法实现循环,这是因为for循环使用可变的状态作为计数器,而while循环或者do-while循环需要可变的状态作为跳出循环的条件。因此函数式语言里面只能用递归来解决迭代问题,这使得函数式编程严重依赖递归。
流计算模式
这个概念来自于SICP里面的第3章,可以理解为unix里面的pipline,使用它可以让代码具有申明式的语义化、模块化,更加富有表现力。
以javascript为例,设计好的风格的代码表现如下:
getAsyncStockData()
.filter(quote => quote.price > 30)
.map(quote => quote.price)
.forEach(price => console.log(`Prices higher than $30: ${price}`));
实用建议
函数中不使用全局变量和IO,有入参和返回值
使用map and reduce对列表进行操作,不使用循环迭代
声明式,而不是命令式
不改变原始数据
参考资料
函数式编程入门教程http://www.ruanyifeng.com/blog/2017/02/fp-tutorial.html
理解函数式编程https://www.cnblogs.com/cpselvis/p/6271008.html