1、编程范式
命令式编程(Imperative Programming): 专注于”如何去做”,这样不管”做什么”,都会按照你的命令去做。解决某一问题的具体算法实现。
函数式编程(Functional Programming):把运算过程尽量写成一系列嵌套的函数调用。
逻辑式编程(Logical Programming):它设定答案须符合的规则来解决问题,而非设定步骤来解决问题。过程是事实+规则=结果。
2、函数式编程的好处
函数式的最主要的好处主要是不变性带来的:
2.1 引用透明(Referential transparency)
引用透明(Referential transparency),指的是函数的运行不依赖于外部变量或”状态”,只依赖于输入的参数,任何时候只要参数相同,引用函数所得到的返回值总是相同的。
其他类型的语言,函数的返回值往往与系统状态有关,不同的状态之下,返回值是不一样的。这就叫”引用不透明”,很不利于观察和理解程序的行为。
没有可变的状态,函数就是引用透明(Referential transparency)
2.2 没有副作用(No Side Effect)
副作用(side effect),指的是函数内部与外部互动(最典型的情况,就是修改全局变量的值),产生运算以外的其他结果。
函数式编程强调没有”副作用”,意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。
函数即不依赖外部的状态也不修改外部的状态,函数调用的结果不依赖调用的时间和位置,这样写的代码容易进行推理,不容易出错。这使得单元测试和调试都更容易。
还有一个好处是,由于函数式语言是面向数学的抽象,更接近人的语言,而不是机器语言,代码会比较简洁,也更容易被理解。
2.3 无锁并发
没有副作用使得函数式编程各个独立的部分的执行顺序可以随意打乱,(多个线程之间)不共享状态,不会造成资源争用(Race condition),
也就不需要用锁来保护可变状态,也就不会出现死锁,这样可以更好地进行无锁(lock-free)的并发操作。
尤其是在对称多处理器(SMP)架构下能够更好地利用多个处理器(核)提供的并行处理能力。
2.4 惰性求值
惰性求值(lazy evaluation,也称作call-by-need)是这样一种技术:是在将表达式赋值给变量(或称作绑定)时并不计算表达式的值,
而在变量第一次被使用时才进行计算。
这样就可以通过避免不必要的求值提升性能。
总而言之,函数式编程由于其不依赖、不改变外部状态的基本特性,衍生出了很多其他的有点,尤其简化了多线程的复杂性,提升了高并发编程的可靠性。