1.函数式编程
FP(Functional Programming):简单来说,函数是变成是一种编程范式,它将电脑运算视为函数的计算,属于结构化编程的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用。
相对于命令式编程是通过修改变量的值来保存当前程序的状态,函数式编程是通过函数来保存程序的状态的,或者说是通过函数创建新的参数或返回值来保存程序状态的。函数一层层的叠加起来,其中每个函数的参数或返回结果来代表了程序的一个中间状态,过程式编程中对变量的修改在这里变成了一次的函数转换。
函数式编程特性:
1.高阶函数
函数式编程是通过高阶函数的特性来使其具有更丰富多变的表达能力的。
具有高阶函数性质的编程语言往往也会支持一等函数,它是高阶函数概念上的超集。 指的是函数和其它数据类型处于平等地位,不搞特殊,可以把函数赋值给其他变量,也可以作为参数传入另一个函数,或者作为别的函数的返回值。
正是高阶函数和一等函数的这些特点,使得函数式编程语言表达能力大大增强,使其能够用函数构建起更高层次、更抽象的模块来解决复杂的问题。
2.没有副作用
函数式编程从它的源头λ演算,就是强调函数计算的纯粹性,每个函数的执行都是没有副作用的,即函数所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。
这使得函数式编程各个独立的部分的执行顺序可以随意打乱。而这在命令式编程的代码中是不可能的。执行顺序的随意特性,使其衍生出许多非常有用的特性,如无锁的并发操作、惰性求值、以及各种在编译器级别上的性能优化技术。
3.尾递归
由于递归在函数式编程中的大量使用,如果使用不当,函数栈将很快使用到爆。于是函数式编程又出现了尾递归特性,使用大量的递归在同一个函数frame中被执行,而不需要为每次函数调用申请一个frame,只要该尾递归设计合理。
正是JVM不支持尾递归,才使基于JVM的函数式编程语言Scala、CloJure光收诟病。
4.闭包
闭包的本质是一等函数,它具有函数的作用并可以像对象一样操作的对象。
5.惰性计算
除了高阶函数和闭包的概念,FP 还引入了惰性计算的概念。在惰性计算中,表达式不是在绑定到变量时立即计算,而是在求值程序需要产生表达式的值时进行计算。延迟的计算使您可以编写可能潜在地生成无穷输出的函数。因为不会计算多于程序的其余部分所需要的值,所以不需要担心由无穷计算所导致的 out-of-memory 错误。一个惰性计算的例子是生成无穷 Fibonacci 列表的函数,但是对第n个Fibonacci 数的计算相当于只是从可能的无穷列表中提取一项。
6.函数是“一等公民”
指函数与其它数据类型一样,出于平等地位,可以赋值给其它变量,也可以作为参数传入另一个函数,也可以作为其它函数的返回值。如我们常用的print函数。
7.只用“表达式”,不用“语句”
"表达式"是一个单纯的运算过程,总是有返回值;"语句"是执行某种操作,没有返回值。函数式编程要求,只使用表达式,不使用语句。也就是说,每一步都是单纯的运算,而且都有返回值。原因是函数式编程的开发动机,一开始就是为了处理运算,不考虑系统的读写(I/O)。"语句"属于对系统的读写操作,所以就被排斥在外。典型的长于计算,弱于I/O。
当然函数式语言不可能真的就不执行I/O,可以通过一些其它手段来把I/O的影响限制到最小,比如通过Continuations、Monad等技术。
具有如下优点:
- 代码简洁,开发快速:函数式编程大量使用函数,减少了代码的重复,因此开发更加高效简洁。
- 接近自然语言,易于理解:函数式编程自由度很高,可以写出十分接近自然语言的代码。
- 方便代码管理:因为函数式编程不依赖也不会改变外界的状态,只要输入参数确定,必然返回相同的结果。因此每个函数都可以看做一个独立单元,这样有利于进行单元测试和模块化组合。
- 易于并发编程:因为函数式编程不修改变量,不存在锁线程的问题,所以无需考虑死锁,也不用担心一个线程的数据被另一个线程修改,所以可以放心地把工作分摊到多个线程,部署并发编程。
- 代码热升级:由于函数式编程没有副作用,只要保证接口不变,每部实现是和外部无关的。所以,可以在运行状态下直接升级代码,无需重启或停机。
2.响应式编程
RP(Reactive Programming):本质上是一种面向数据流和变化传播的编程思想,可以很方便地表达静态或动态的数据流,相关的计算模型会自动将变化的值通过数据流进行传播。
响应式编程具有以下特点:
- 异步编程:响应式编程提供了异步编程模型,能够挖掘多核CPU的性能,提高运算效率、降低延迟和阻塞等。
- 基于数据流:响应式编程基于数据流模型,提供一套统一的Stream特点的数据处理接口。除了支持静态数据流、还支持动态数据流,并且支持复用和同时接入多个订阅者。
- 变化传播:简而言之就是以一个数据流为输入,经过一系列操作转化为另一个数据流,然后分发给各个订阅者的过程。类似函数式编程中的组合函数,将多个函数串联起来,转化为格式迥异的输出数据。
响应式编程不仅在用户界面应用领域以及基于实时系统的动画方面都有广泛的应用,而且在处理嵌套回调的异步事件、复杂的列表过滤和变换也都有良好的表现。
如今的移动应用中,不论基于原生、H5、还是Hybrid,都会有大量的基于数据流的UI事件发生,这时使用响应式编程便会更加得心应手。
3.函数响应式编程
FRP(Functional Reactive Programming):将函数式编程中的思路与响应式编程结合起来的,便形成了函数响应式编程,结合了二者的优点。主要关注导致状态值改变的行为事件,一系列事件组成了事件流。
其核心包括两个核心观点:
- 事件流:离散事件序列;
- 属性properties:代表模型连续的值。
一系列事件正是引起属性值发生变化的原因,FRP能够更加高效地处理事件流,而无需显式去管理状态。
而在实际的开发中,UI操作与状态的变化越来越复杂的情况下,函数响应式编程的这些特点便能够充分发挥其优势。
参考资料:
1.http://janfan.cn/chinese/2015/05/18/functional-programming.html
2.https://www.jianshu.com/p/0c8a692a0c7f
3.https://www.jianshu.com/p/917474eda91c
4.http://emacoo.cn/backend/reactive-overview