本文主要介绍了什么是functional programming (简称FP),FP有什么特点以及FP的优势,并澄清FP相关的一些概念。
什么是functional programming
我们都知道procedural programming(面向过程的编程)和object-oriented programming(面向对象的编程)这两种编程范式;而functional programming(函数式编程)则是一种新的编程范式。不过其实FP也算不上新的概念了,因为John Backus在1977年就提出了这个概念。
Wikipedia上的对functional programming的定义如下:
In computer science, functional programming is a programming paradigm—a style of building the structure and elements of computer programs—that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data
Function(函数)原本是数学上的一个概念,FP就是用数学上函数运算的思维方式来处理计算机编程问题。FP的一个重要的特点就是没有副作用(no side effect)。函数运算过程中不会修改任何状态,函数的计算结果只与输入参数相关,用相同的输入参数多次调用同一个函数,永远会得到相同的结果,因此FP具有幂等性(idempotent)。
零君以前写的一篇介绍HTTP协议中POST和PUT区别的文章,就提到了幂等(idempotent)这个概念。有兴趣的童鞋可以翻看历史文章。
declarative programming vs imperative programming
这两个概念虽然简单,但深刻理解这两个概念对于一个软件工程师来说至关重要,所以单独提出来强调一下。
declarative programming是指声明式编程,编程的思维方式是告诉程序要干什么。imperative programming是命令式编程,思维方式则是告诉程序具体怎么做。通常来说,声明式编程方式抽象程度更高,也更容易理解。
Functional programming就是一种声明式编程。
First-Class Function vs High-Order Function
有一些概念与Functional programming密切相关,限于篇幅,这里只介绍First-Class function和High-Order Function。
High-Order Function(高阶函数)是一个数学上的概念,而First-Class Function(一类实体函数)则是一个计算机中的概念。
实在想不出一个贴切的中文名词来表达First-Class Function,这里姑且称其为一类实体函数。
High-Order Function是指可以接受其它函数作为参数,或者将其它函数作为结果返回的函数。First-Class Function则是指可以像其它一类实体一样自由使用的函数。例如一个整数既可以作为函数的参数,也可以作为函数的返回值,那么First-class function同样既可以作为其它函数的参数,也可以作为函数的返回值。也就是其它一类实体(例如:整数)可以使用的地方,也可以使用First-Class Function。
Functional programming的优势
由于FP没有副作用,函数运算过程中不会修改任何状态的值,运算结果只依赖于输入参数。因此就可以安全的缓存中间计算结果,如果以后遇到相同的参数调用同一个函数,就可以直接返回缓存的结果,从而提高计算效率。
因为程序都是由一个个没有副作用的函数组成,所以程序的可测性也很好。
因为FP是declarative programming(声明式编程),因此程序容易理解,而且抽象程度高。这一点前面也提到过。
Functional programming示例
这里用几种编程语言简单演示一下如何使用经典的filter/map/reduce这些高阶函数的示例。假设有一个整数列表,现在要计算列表中小于10的整数的平方和。
Ruby
#!/usr/bin/ruby
vs = [1, 2, 3, 12, 20]
puts "#.map{|item| item * item}.reduce{|sum, item| sum += item}}"
Java
Java在JDK8中增加了对FP的支持,但要注意一点,虽然函数/lambda表达式可以作为参数或返回值,但是它们并不是与其它一类实体同等看待的,而是作为functional interface。
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
public class functional {
public static void main(String[] args) {
List list = new ArrayList(Arrays.asList(1, 2, 3, 12, 20));
}
}
Golang
因为golang中没有现成filter/map/reduce实现,所以实现稍麻烦。这里就不贴源代码了,感兴趣的童鞋可以自行阅读:
https://github.com/ahrtr/go_functional
虽然上面列举了Ruby/Java/Golang的例子,但其实真正的functional programming language是下面这些:
Clojure
Elixir
Elm
F#
Haskell
Idris
Scala
展望
虽然FP概念很早就提出来了,而且也有不少FP的编程语言,在商业软件中也有一些应用,但与Java/C/C++/JavaScript这些语言比起来,流行程序明显就差一大截。FP更多的是存在于实验室环境中。
回顾历史,OOP(面向对象编程)模式后来居上,显然超过了面向过程的编程模式。而对于FP将来实际会如何发展,还很难说,毕竟这个概念很早就提出来了,而且也有了不少语言,但经过这么多年的发展,还是没有大规模流行起来。
--END--
领取专属 10元无门槛券
私享最新 技术干货