高阶函数的本质是什么?

134 阅读4分钟

所谓高阶函数,就是能操纵其他函数的函数。

这么说很 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 这个高阶函数,他把文本处理中的模式固化下来的,使得其他的函数的工作可以单一化,无脑化,极致简化。

我们生活中也是这样。

很多人都不明白,生活中最难得事情,并不是做事,而是安排他人做事,以及在事后进行合理的分配。大学的政治老师说,这个就是政治学的本质。

经济学的本质是生产,政治学的本质是分配。合理分配是社会中最难的事情,所以政治是经济的上层建筑。

许多人都希望自己有一个好领导,他会好好安排我的工作,让我可以只专注于做一件事情,并把它做好。这样我的工作也更加容易被评价。

这个是不是在说你呢,至少我团队的同学,就经常对我提这个要求呢。

就连打工人都梦想单线程工作,知道这样好做事情,更何况是系统中的函数呢?

是这样吗?

软件代码中不能没有高阶函数,正如生活中不能没有会安排工作的领导,他们都是系统安定繁荣的基石。