![](https://csdnimg.cn/release/download_crawler_static/86280316/bg4.jpg)
极客时间
http://139.196.35.134/time/#/article/2711[2018/8/1 9:58:43]
higher order function
(高阶函数)
:所谓高阶函数就是函数当参数,把传入的函数做一个封装,然后返回这个封装函数。现象上就是函数传进传出,就像面向对象对象满天飞一
样。这个技术用来做
Decorator
很不错。
上面这些技术太抽象了,我们还是从一个最简单的例子开始。
// 非函数式,不是pure funciton,有状态
int cnt;
void increment(){
cnt++;
}
这里有个全局变量,调这个全局函数变量
++
,这里面是有状态的,这个状态在外部。所以,如果是多线程的话,这里面的代码是不安全的。
如果写成纯函数,应该是下面这个样子。
// 函数式,pure function, 无状态
int increment(int cnt){
return cnt+1;
}
这个是你传给我什么,我就返回这个值的
+1
值,你会发现,代码随便拷,而且与线程无关,代码在并行时候不用锁,因为是复制了原有的数据,并返回了新的数据。
我们再来看另一个例子:
def inc(x):
def incx(y):
return x+y
return incx
inc2 = inc(2)
inc5 = inc(5)
print inc2(5) # 输出 7
print inc5(5) # 输出 10
上面这段Python的代码,开始有点复杂了。我们可以看到上面那个例子inc()函数返回了另一个函数incx(),于是可以用inc()函数来构造各种版本的inc函数,比
如:inc2()和inc5()。这个技术其实就是上面所说的 currying 技术。从这个技术上,你可能体会到函数式编程的理念。
把函数当成变量来用,关注描述问题而不是怎么实现,这样可以让代码更易读
。
因为函数返回里面的这个函数,所以函数关注的是表达式,关注的是描述这个问题,而不是怎么实现这个事情
。
Lisp
语言介绍
要说函数式语言,不可避免地要说一下
Lisp
。
下面,我们再来看看Scheme语言(Lisp的一个方言)的函数式玩法。在Scheme里,所有的操作都是函数,包括加减乘除这样的东西。所以,一个表达式是这样的形式—— (函数
名 参数1 参数1)
上面三个函数:
用内置的 + 函数定义了一个新的 plus 函数。
用内置的 * 函数定义了一个新的 times 函数。
用之前的 times 函数定义了一个 square 函数。
下面这个函数定义了:
f(x) = 5 * x^2 +10
也可以这样定义
——
使用
lambda
匿名函数。
在上面的这个代码里,我们使用 lambda 来定义函数 f2 ,然后也同样用 lambda 定义了两个函数—— plus 和 times。 最后,由 (plus 10 (times 5 (times x x))) 定
义了 f2 。