毫无干货的带你理解什么是函数式编程
ps:这篇文章我推翻重写了好几版换了各种表达方式。最终决定用这种毫无"干货"全是"水文"的方式表达函数式编程的思想。嗯主要是理解思想,希望各位道友看的开心。
世界模型
如果让你搭建一个模型来描述这个世界你会怎么做?
面向对象
面向对象
之父Alan Kay
给我们带来了一种抽象化世界的方法。
一切事物皆对象,通过面向对象的方式,将现实世界的事物抽象成对象,现实世界中的关系抽象成类、继承,帮助人们实现对现实世界的抽象与数字建模。
因此我们有了面向对象式的编程式范。
函数式
这里本来应该引入《范畴论》的概念,不过在这里引入似乎会把事情搞的更复杂,所以先不去理会它,直接看结果。
世界就是由事物和事物之间的关系构成的
下面是一个空无一物的世界:
image.png
世界中有一个a
:
世界中有了事物a
和b
,还有他们之间的关系f
,即使他们之间没关系也可以用f
来表示,只不过f
等于null
。
我们的世界更加丰富了:
image.png如果我们继续这样画下去我们可以画出一个足够复杂的世界。不过到这里已经足够了。
- 把关系
f
作用到a
上可以得到b
- 把关系
g
作用到b
上可以得到c
- 把关系
h
作用到a
上可以得到c
- 其中
h = g.f
让我们再次进行抽象,抽取他们的共性部分。
image.png
所以我们得到了一个结构:a
表示事物,f
表示关系。把f
作用到a
上我们就可以得到b
。
要知道一切真理都是包含在特定的上下文
中的(除了这一句)。所以我们的事物a
也应该包含在上下文中它才是真正的a
,所以我们得到的b
也是上下文中的b
。
(这张图看起来像是a
是印在盒子上的而不是在盒子内部,不要在意这些细节它是在盒子里的)
我们来用一个算式来验证一下模型计算1+2+4
的值:
我们再来一个用户登录的模型,用户名和密码长度都大于0
的时候才可以登录:
上面的做法和直接写语句有什么不同?
- (BOOL)canLoginUserName:(NSString *)username password:(NSString *)password{
if (username.length > 0 && password.length > 0) {
}else{
}
}
拆分方式不同,图中拆分成了:
-
username
和它的关系length>0
,得到结果YES
-
password
和它的关系length>0
,得到结果YES
- 两个
YES
和它的关系&&
,得到结果YES
结论:
- 如果你把世界拆分成
类
,对象
你就得到了面向对象
。 - 如果你把世界拆分成
事物
和事物之间的关系
你就得到了函数式
。
好了道友们,看到这里你可以怀着愉快的心情关上电脑,闭上眼睛,深呼吸,思考一下如何按照事物
和事物之间的关系
的方式来拆分世界,你就已经掌握了函数式编程的思想。
简单对比
-
面向对象
的世界里我们是把事物
抽象成类
和对象
,然后通过封装
、继承
和多态
来演示他们之间的关系。 -
函数式
的世界里把世界抽象成事物
和事物之间的关系
,用这种方式实现世界的模型。
面向对象的编程更有人情味一些更社会化。比如你想要买一辆汽车,想要托人帮忙砍价。恰好你同学的朋友的大表哥的二嫂子在4s店工作。你就需要:
import "同学"
import "朋友"
import "大表哥"
import "二嫂子"
然后再调用二嫂子.砍价();
函数式编程则更“冰冷”一些,像是工厂里的流水线不停的运转,只要你放入材料就可以在出口处拿到产品。而且它对外部环境没有依赖,只需要将流水线搬走就可以在任何地方生产。不需要找同学的朋友的大表哥的二嫂子来帮忙了。
整理了几篇干货资料,有兴趣的道友可以看看: