所谓高阶函数,就是能操纵其他函数的函数。
这么说很 fancy,高阶函数有什么用?何德何能,被称高阶呢。
所谓高阶,其实是一个中文翻译的小把戏,出于不伤害大众感情的目的。英文是 higher order,直译是统治阶级,是一个政治学的术语。就是说这些函数是系统中的统治阶级 。
在古欧洲,higher order 几乎是特指教会的高阶祭师们,因此也可以被翻译为贵族函数。
我们的软件系统,正如真实的社会,其中必然存在制定规则,维护规则,充当统治阶级的函数,也有工作单一僵化,专注于做事的函数。
如果没有社会中的统治阶级制定规则,安排工作,普通人就会陷入无序繁忙的状态中。
真实的系统和社会并不是起点小说,其底层逻辑残酷而现实。
软件系统的构造,和社会有共同之处,阶级对立无处不在呢。
没有对立,就不可能有和谐,正如没有光明,就不会有黑暗,最光明的地方,隐藏做最深的黑暗。
宇宙夜空中那颗最亮的星星,最终会成为吞噬一切的最大的黑洞。
没有阶级划分,人人平等的社会,最终必然会陷入无政府状态而崩溃。
中国有句古话,劳心者治人,劳力者治于人。
这里没有褒贬,只是社会分工不同,社会中必然会出现只专注做给别人派活的职业经理人(高人),也会有大量被傻子领导随意指派,只梦想着单线程工作的打工人。
劳心者就是高人,即,操纵别人生活的人,他们的工作就是制定其他人生活的规则,使得社会中的普罗大众各安其位,社会也就安定繁荣了。
高阶函数在软件开发中的作用,完全和高人是一样的,它的作用就是制定规则,使得系统的其他函数各安其位,系统也就和谐稳定了。
制定规则,也可以说是固化模式。
所以 FP 领域中的同学,一般不讲设计模式,因为大多数设计模式都已经被各种高阶函数固化了。
map/reduce 就是最经典的高阶函数,固化了大数据处理的本质。
现在说回我的深度阅读插件。 比如在插件开发的文本处理中,经常有一种情况,某个操作的执行是需要满足一定条件的。
譬如说下面种情况,如果检查到这段文本长度过大,那么我们要把它拆分成两个段落。
新人写代码,只会定义一个函数,比如这样。
const split_para = txt => if (txt.length > 49) txt.split(':');
array.map(split_para);
但从 FP 的开发来看,他应该被分成三个函数才是合理的:
- 第一个 process_if,这是一个高阶函数,用来固化“碰到条件就执行某个文本处理函数”这个模式。
- 第二个 is_too_long 这个函数是只做条件判断。
- 第三个 split_para 这个函数只做文字拆分。
最后的结果是
array.map(process_if(is_too_long)(split_para))
.map(process_if(is_speech)(break_speeck))
这样你的所有函数都只是专注于做一件事情,你的代码单元测试的难度将会指数级的下降。 这里的关键就是 process_if 这个高阶函数,他把文本处理中的模式固化下来的,使得其他的函数的工作可以单一化,无脑化,极致简化。
我们生活中也是这样。
很多人都不明白,生活中最难得事情,并不是做事,而是安排他人做事,以及在事后进行合理的分配。大学的政治老师说,这个就是政治学的本质。
经济学的本质是生产,政治学的本质是分配。合理分配是社会中最难的事情,所以政治是经济的上层建筑。
许多人都希望自己有一个好领导,他会好好安排我的工作,让我可以只专注于做一件事情,并把它做好。这样我的工作也更加容易被评价。
这个是不是在说你呢,至少我团队的同学,就经常对我提这个要求呢。
就连打工人都梦想单线程工作,知道这样好做事情,更何况是系统中的函数呢?
是这样吗?
软件代码中不能没有高阶函数,正如生活中不能没有会安排工作的领导,他们都是系统安定繁荣的基石。