Skip to main content

函数式编程介绍

最近在研究JDK8的新特性,一直熟悉面向过程和面向对象的编程模式,突然发现没怎么了解过函数式编程,于是最近乘这个机会,研究了一下函数式编程。

bg2012040601

定义
简单说,”函数式编程”是一种”编程范式”(programming paradigm),也就是如何编写程序的方法论。
它属于”结构化编程”的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用。函数,大家应该都了解,就是一个功能逻辑单元,它没有特定的属性和归属。
函数式编程(FP)的核心就是一切都是函数,也就是说”活“的不再是对象,而是函数。函数本质是x到f(x)的变换,所以FP的元素就两种,一种是函数(”pure function“的概念,表现为命名句柄或表达式,所以独立性->并发性),一种是状态(immutable,因为只要发生变换,就通过函数表现)。 函数的独立性,导致了我们没法记录函数内部运行的状态,怎么解决呢,把状态放在参数里呗,然后用递归来搞定。

函数式编程的特点

    函数式编程的三大特性:
  • immutable data 不可变数据:像Clojure一样,默认上变量是不可变的,如果你要改变变量,你需要把变量copy出去修改。这样一来,可以让你的程序少很多Bug。因为,程序中的状态不好维护,在并发的时候更不好维护。(你可以试想一下如果你的程序有个复杂的状态,当以后别人改你代码的时候,是很容易出bug的,在并行中这样的问题就更多了)
  • first class functions:这个技术可以让你的函数就像变量一样来使用。也就是说,你的函数可以像变量一样被创建,修改,并当成变量一样传递,返回或是在函数中嵌套函数。这个有点像Javascript的Prototype(参看Javascript的面向对象编程)
  • 尾递归优化:我们知道递归的害处,那就是如果递归很深的话,stack受不了,并会导致性能大幅度下降。所以,我们使用尾递归优化技术——每次递归时都会重用stack,这样一来能够提升性能,当然,这需要语言或编译器的支持。Python就不支持。
    函数式编程的几个技术
  • map & reduce :这个技术不用多说了,函数式编程最常见的技术就是对一个集合做Map和Reduce操作。这比起过程式的语言来说,在代码上要更容易阅读。(传统过程式的语言需要使用for/while循环,然后在各种变量中把数据倒过来倒过去的)这个很像C++中的STL中的foreach,find_if,count_if之流的函数的玩法。
  • pipeline:这个技术的意思是,把函数实例成一个一个的action,然后,把一组action放到一个数组或是列表中,然后把数据传给这个action list,数据就像一个pipeline一样顺序地被各个函数所操作,最终得到我们想要的结果。
  • recursing 递归 :递归最大的好处就简化代码,他可以把一个复杂的问题用很简单的代码描述出来。注意:递归的精髓是描述问题,而这正是函数式编程的精髓。
  • currying:把一个函数的多个参数分解成多个函数, 然后把函数多层封装起来,每层函数都返回一个函数去接收下一个参数这样,可以简化函数的多个参数。在C++中,这个很像STL中的bind_1st或是bind2nd。
  • higher order function 高阶函数:所谓高阶函数就是函数当参数,把传入的函数做一个封装,然后返回这个封装函数。现象上就是函数传进传出,就像面向对象对象满天飞一样。
    函数式编程的优势
  • 代码简洁,开发快速。函数式编程大量使用函数,减少了代码的重复,因此程序比较短,开发速度较快
  • 接近自然语言,易于理解。函数式编程的自由度很高,可以写出很接近自然语言的代码。
    比如表达式(1 + 2) * 3 – 4,如果用函数式编程格式,如下:

    add(1,2).multiply(3).subtract(4)

    它更接近我们人的表达方式,更容易理解。其实好的程序是人更容易理解,而不是让机器更容易。
  • parallelization 并行:所谓并行的意思就是在并行环境下,各个线程之间不需要同步或互斥。
  • determinism 确定性:所谓确定性的意思就是像数学那样 f(x) = y ,这个函数无论在什么场景下,都会得到同样的结果,这个我们称之为函数的确定性。而不是像程序中的很多函数那样,同一个参数,却会在不同的场景下计算出不同的结果。所谓不同的场景的意思就是我们的函数会根据一些运行中的状态信息的不同而发生变化。因此函数式编程不依赖、也不会改变外界的状态,只要给定输入参数,返回的结果必定相同。每一个函数都可以被看做独立单元,很有利于进行单元测试(unit testing)和除错(debugging),以及模块化组合。

参考
https://en.wikipedia.org/wiki/Programming_paradigm
http://coolshell.cn/articles/10822.html
http://www.ruanyifeng.com/blog/2012/04/functional_programming.html

我是一个Coder

我是一个Coder,毕业七八年,写的语言从C, C++, Java开始,熟练掌握的也不下十几种了。我不是什么大神,顶多算是个代码熟练工。作为一个代码搬运工,在公司年复一年的耕耘,带着码农固有的宅,下班在家之余也七七八八写了不少代码,乐此不疲。

一日,和朋友聊到此事,作为极度的代码爱好者,大有同感。于是我们自己掏腰包,购买了个阿里云服务器,成立了这个网站。我们本着开放的态度,把我们的代码与大家分享。或者,心血来潮,会出一些技术视频教程。