01-什么是函数式编程
什么是函数式编程
函数式编程的基础模型来源于 λ 演算,而 λ 演算并没有设计在计算机上执行。它是由 Alonzo Church 和 Stephen Cole Kleene 在 20 世纪 30 年代引入的一套用于研究函数定义、函数应用和递归的形式系统。
如:f(x) = f(x-1) + f(x-2)
它关心的是定义输入数据和输出相关的关系,数据表达式其实是在做一种映射(mapping),输入的数据和输出数据关系是什么,是用函数来定义的。
函数式编程核心:
- 输入:不可变的值
- 函数:一种映射关系,将一个值映射成另外一个值
函数式编程特性
-
不可变:输入数据是不能改变的,返回的是全新的数据集
-
无状态:函数不维护任何状态
函数式编程优势
-
线程安全;因为没有状态,所以并行执行是安全的
-
重构代码无伤害
-
函数的执行没有顺序上的问题
函数式编程劣势
- 数据复制严重;因为输入数据是不可以改变的,严重占据运行资源
- 纯函数编程比较难实现;如java
函数式编程思维
函数式编程关注的是:describe what to do, rather than how to do it。于是,我们把以前的过程式编程范式叫做 Imperative Programming – 指令式编程,而把函数式编程范式叫做 Declarative Programming – 声明式编程
所以函数式编程关注的是做什么而不是怎么做;因此函数式编程抽象是对行为的抽象
函数式编程与面向对象编程区别
函数式编程 | 面向对象编程 |
---|---|
关注做什么;行为上的一种抽象 | 关注是什么;数据上的一种抽象 |
函数是一等功名,同数据是一样的地位 | 对象是程序的基本单元;包含属性和方法 |
无状态;无副作用 | 有状态;属性可以改变,有副作用 |
语法自由 | 健壮性好 |
代码简洁,可读性强 | 封装、继承、多态;代码灵活、可扩展 |
面向对象编程的优点
面向对象程序设计可以看作一种在程序中包含各种独立而又互相调用的对象的思想,这与传统的思想刚好相反。传统的程序设计主张将程序看作一系列函数的集合,或者直接就是一系列对电脑下达的指令。面向对象程序设计中的每一个对象都应该能够接受数据、处理数据并将数据传达给其它对象,因此它们都可以被看作一个小型的“机器”,即对象。目前已经被证实的是,面向对象程序设计推广了程序的灵活性和可维护性,并且在大型项目设计中广为应用。此外,支持者声称面向对象程序设计要比以往的做法更加便于学习,因为它能够让人们更简单地设计并维护程序,使得程序更加便于分析、设计、理解。同时它也是易拓展的,由于继承、封装、多态的特性,自然设计出高内聚、低耦合的系统结构,使得系统更灵活、更容易扩展,而且成本较低。
面向对象编程的缺点
面向对象编程以数据为核心,所以在多线程并发编程中,多个线程同时操作数据的时候可能会导致数据修改的不确定性。
函数式编程的优点
在函数式编程中,由于数据全部都是不可变的,所以没有并发编程的问题,是多线程安全的。可以有效降低程序运行中所产生的副作用,对于快速迭代的项目来说,函数式编程可以实现函数与函数之间的热切换而不用担心数据的问题,因为它是以函数作为最小单位的,只要函数与函数之间的关系正确即可保证结果的正确性。
函数式编程的表达方式更加符合人类日常生活中的语法,代码可读性更强。实现同样的功能函数式编程所需要的代码比面向对象编程要少很多,代码更加简洁明晰。函数式编程广泛运用于科学研究中,因为在科研中对于代码的工程化要求比较低,写起来更加简单,所以使用函数式编程开发的速度比用面向对象要高很多,如果是对开发速度要求较高但是对运行资源要求较低同时对速度要求较低的场景下使用函数式会更加高效。
函数式编程的缺点
由于所有的数据都是不可变的,所以所有的变量在程序运行期间都是一直存在的,非常占用运行资源。同时由于函数式的先天性设计导致性能一直不够。虽然现代的函数式编程语言使用了很多技巧比如惰性计算等来优化运行速度,但是始终无法与面向对象的程序相比,当然面向对象程序的速度也不够快。
总结
函数式编程关注的做什么;其实就是输入和输出的一种映射关系,其状态不可变,所以线程安全。
函数式编程和面向对象编程各有利弊,一个语法更加自由,一个健壮性更好。作为程序员应该对两种编程方式都有所了解,不管是哪种方式,只要能够很好的解决当前的问题就是正确的方式,毕竟对于软件工程来说解决问题是最主要的,用的工具反而没有那么重要,重要的是解决问题的思想。
网友评论