概念:
简单说,"函数式编程"是一种"编程范式"(programming paradigm),也就是如何编写程序的方法论。
它属于"结构化编程"的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用。 ---《百度百科》
特点:
1. 函数是"第一等公民"
所谓"第一等公民"(first class),指的是函数与其他数据类型一样,处于平等地位,可以赋值给其他变量,也可以作为参数,传入另一个函数,或者作为别的函数的返回值。
这种设置在JavaScript中得到最完备的体现,在Java、Python等语言中则不具备这一点。
2. 只用"表达式",不用"语句"
"表达式"(expression)是一个单纯的运算过程,总是有返回值;"语句"(statement)是执行某种操作,没有返回值。函数式编程要求,只使用表达式,不使用语句。也就是说,每一步都是单纯的运算,而且都有返回值。
3. 没有"副作用"
所谓"副作用"(side effect),指的是函数内部与外部互动(最典型的情况,就是修改全局变量的值),产生运算以外的其他结果。
函数式编程强调没有"副作用",意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。
4. 不修改状态
状态一般是通过变量来保存,不修改状态意味着不能修改输入值,而是每次返回输出值,通过输出保存状态。
5. 引用透明
引用透明(Referential transparency),指的是函数的运行不依赖于外部变量或"状态",只依赖于输入的参数,任何时候只要参数相同,引用函数所得到的返回值总是相同的。
6. 惰性计算
在惰性计算中,表达式不是在绑定到变量时立即计算,而是在求值程序需要产生表达式的值时进行计算。延迟的计算使您可以编写可能潜在地生成无穷输出的函数。因为不会计算多于程序的其余部分所需要的值,所以不需要担心由无穷计算所导致的 out-of-memory 错误。
在我的理解中,第2~4点是一致的,通过不修改状态、使用返回值,达到没有副作用的效果。
优点:
1. 代码简洁,开发快速
2. 接近自然语言,易于理解
3. 更方便的代码管理
4. 易于"并发编程"
理解:
关于Java1.8 lambda表达式及Stream中应用了函数式编程,但并不完全符合上述纯粹的函数式编程。
首先在Java中,函数是以接口(方法)的形式支持的,所以并不是第一等公民。
其次,函数并不是只用表达式,不用语句,有些函数是会修改输入变量,所以也并不是完全没有副作用。
另外,惰性计算在stream中得到充分的利用,stream的两类操作:转换操作和聚合操作,转换操作就是惰性计算,而聚合操作只能执行一次。
但stream的出现还是大大简化了集合的处理,将集合和数组以数学运算的方式进行增、删、改、查、聚合、统计、过滤等处理,处理过程更加接近自然数学运算,便于理解和管理。