函数式编程

昨天在维基百科上看了个叫functional programming的条目,金山词霸管functional programming叫“函数式编程”,下面我就用这个翻译行文好了。那条目有点长,我看完后,觉得好像懂了,又好像不全懂,似是而非的,于是做一下学习笔记。

按照那条目的意思,函数式编程是和imperative programming(词霸管那叫“命令式编程”)相对的,两者都是一种编程的paradigm(范式?)。前者讲的是用数学函数般的方法去解决问题,尽量避免状态(state)和可变数据(mutable data),而后者则强调状态和状态之间的转换。好像挺抽象的,文章后面还有一个解释:命令式编程是强调解决问题过程中的一系列步骤和动作,函数式编程强调的是函数的组合而往往没有显式的步骤(emphasize the composition and arrangement of functions, often without specifying explicit steps)。仍然比较抽象,还是直接上例子好了(下面例子直接复制自维基原条目):

命令式编程

# imperative style

target = [] # create empty list

for item in source_list: # iterate over each thing in source

    trans1 = G(item) # transform the item with the G() function

    trans2 = F(trans1) # second transform with the F() function

    target.append(trans2) # add transformed item to target

函数式编程

# functional style

# FP-oriented languages often have standard compose()

compose2 = lambda F, G: lambda x: F(G(x))

target = map(compose2(F,G), source_list)

代码是用python写的,由此可见python既支持命令式编程,又支持函数式编程,是一种multi-paradigm的编程语言。代码很简单,对于不熟悉python的观众,仅需要解释一下lambda就可以了:

# python的lambda statement就是构造并返回一个函数,比如

f = lambda x: x * x



# 这样变量f就指向一个函数,这个函数接受一个参数x,返回x的平方,比如f(2)结果是4,等等

那么,lambda里面又lambda,就是说这个函数的返回值是另一个函数,即在维基的第二段例程里面,外层的那个lambda构造的是一个接受两个参数(F、G),返回值是内层lambda的函数,而内层的lambda又构造了一个接受一个参数(x),返回值是F(G(x))的函数。

而map是python另一个重要的内建函数,在例程里面,它的作用是遍历source_list里面的每一个element,对每一个element调用compose2,把计算结果放入另一个list里面,最后,这个装满计算得数的list被赋值给了target。

两段例程的结果是一样的,分析代码很容易看到:命令式编程的解决问题方法就是我们初学C、Pascal时的方法,变量、步骤、状态、求解,这也是传统的编程范式;函数式编程就是尽量消除中间变量、步骤、状态,像求解代数问题一样,每个步骤都是函数(可能我这样说不恰当……)

 


 

支持函数式编程的语言,就是支持函数式编程这种paradigm的编程语言,上面已经看到有python这种multi-paradigm的语言,还有的是纯函数式编程语言,如Haskell,这个没有学过就不说了,接下来说说函数式编程语言的一些特征:

High-order functions。这个不晓得怎翻译了,简单地概括,就是说函数本身可以作为参数传递给另一个函数,也可以作为另一个函数的返回值。由上例可知,python可以直接做到这个,原文提到C语言可以用函数指针来模拟这个,C++/Java也可以模拟(用functor还是其他什么?很久没有用过这两种语言了……)。

Pure functions。纯函数,所谓纯,就是没有副作用,所谓副作用,就是函数内部修改了共享变量(如全局变量、外层函数里面的局部变量等等)、有I/O动作、对于相同的输入不一定得到相同的结果(例子就是random一类的函数,还有就是记录了内部状态的函数,每次结果都可能不一样)。纯函数是不能有这些“副作用”的,也正因为没有副作用,所以纯函数是线程安全(thread-safe)的。

还有另外几点,有些是和编译器/解释器有关的,直接看原文好了。

 


 

看了那文章后,我的感觉就是纯函数式编程语言可能很难在通用的应用领域有作为,反而一些支持多种编程paradigm的语言,如python,比较好玩,因为某些时候用函数式风格编程,会让代码特简洁(甚至看上去很优雅),如原文所举的例子。另外,对于python来说,就我所知,在某些时候用函数式风格编程,会获得更高的效率,如上文提到的用map对一个iterable序列作遍历运算,就比for循环来得高效,类似的还有python的list-comprehension,详细的说明可以看python自带的tutorial。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值