LOADING...

加载过慢请开启缓存(浏览器默认开启)

loading

说说 FP 和 OOP

前几天听之前两同事在争论 FP 和 OOP 的优劣,比较有趣(尴尬)的是,甲呢,是一个不熟悉 FP 的 FP 狂热粉,乙呀,又是一个分不清 OOP 和模块化的 OOP 粉。

同之前我写的,学 RE(正则表达式),基础的可以参考《Introducing Regular Expressions》,但是想有深入理解的,最好看看《Intermediate Perl》中的正则部分,本文大多数是从其他非主要 FP/OOP 的书来说它们的,像很多人想了解 FP,实际上看相关的书,如:

  • 《Functional Thinking》,主要是讲 FP 能够延伸的一些概念
  • 《Functional XX》(XX 为 语言)一系列的书,主要是讲 XX 语言里头的函数式方法的使用

反而会得出很多模糊的概念。

我的 FP 经历

  1. 《Programming in D》,从 D 语言开始说起,这是我第一次接触到 pure 声明的函数和函数式方法,当时网络并没有多少 FP 的信息,但是像 pure 声明的函数,我一直怀疑其存在的意义,D 语言给我的 FP 粗浅理解就是:纯粹,函数没有副作用,输入什么就确定输出什么
  2. 《实用Common Lisp编程》,我是从田春翻译的这本书开始学习 Common Lisp,但是如果真想系统学习 Common Lisp 还是建议《ANSI Common Lisp》等高质量的书,不是这种面向应用的书,而且现在 Apress 出版的书简直就是摘要书。Lisp 方言的语言基本都不是纯函数式,而是多范式语言,这点别被网络误导了,Lisp 一个让人难忘的点就是,万物你都想 lambda,函数传来传去的,相当好用。于是当代很多非纯函数式语言都是通过传入的高阶函数给纯函数的方式,提供函数式方法(如 mapfilter 等)的功能的。这时候,FP 就需要:函数是第一公民
  3. 《Programming Erlang》,Erlang 是我第二门接触到的纯函数式语言,其中最让人犯难的一个点就是其变量的不可变,函数式理论上很好的东西,可是当全部都不可变,编程便加了很多难度,而且像哈希表等常用数据结构的性能一直没有好的答案可以解决,于是纯 FP 给留我了一个又爱又很的特征:不可变性
  4. 《Learn You a Haskell》,Haskell 是我第一次接触的纯函数式语言,对于其中的对象一开始没有注意,后面在 FP 潮兴起的时候,莫名想起它居然有对象,然后温习一遍,才知道自己对于 OOP 和 FP 的误解:对象和 FP 并不互斥,对象并非是区分 OOP 和 FP 的东西
  5. 《Programming Scala》,记忆比较模糊了(因为 Scala 真的难学难用难懂,还它瞄的慢),Scala 本身是一门函数式和面向对象的双范式语言,它对 OOP 和 FP 思维的划分方式,比较符合我的预期,总结起来大概是:OOP 和 FP 是思维方式的不同,OOP 是属性和行为的结合,绑定在一起,FP 则是拆分了对象和行为,进行各种组合

总结 FP

函数式特性有纯粹、不可变性、支持高阶函式。函数式编程就是不打破它的特性写代码,为了更好表达函数式编程的思想,最好是要有函数式思维,拆分对象和行为,当然啦,你可以在 OO 语言中进行 FP,只要你遵循函数式特性。函数式编程语言就是带有函式是特性的语言,你无法打破特性,同样的,只要你要愿意,也可以 OOP。

大众的 OOP 误解

因为 Java/C++ 的对象,受众广、易理解,早已深入人心,以至于一旦出现 OOP,大多数人都会以 Java/C++ 的特点来惯性解释 OOP。所以很多 Javaer 理解的就是封装、继承、多态。其实我们要有个层次认知:

  • OO
  • OOP
  • XX 语言的 OOP

XX 语言的 OOP 会加入设计者来补充和完善自己对 OO 的理解,所以 OOP 不代表是就有封装继承多态等特性,但是 Java 的 OOP 有者三特性来表达自己的 OO。

劝言

  1. OOP 在 FP 热潮下被黑得过惨,其实 OOP 非常优秀,只不过错用,不懂的人一大堆,还都以为用了 Java/C++ 等就是 OOP。
  2. FP 和 OOP 可以相辅相成,并非互斥
  3. 认真看待 FP 和 OOP 的优劣,现在 FP 或 OOP 的传播者,很多是二极管,非黑即白,因为 A 的优点就抹杀 B 的优点,因为 A 的一个缺点就否定 A 的全部
  4. 纯 FP 语言学习或做自己项目可以,工作工程上的要慎重考虑