最近读了点 rambda 的源码。函数式是个很诱人的概念,借助函数式,你可以以十分数学的方式解决一些问题。虽然如此,函数式对于现实来说仍然过于抽象,如果我们不去关注底层,那他确实是好的,然而一旦我们逼视其实现,我们就会发现它的窘迫与骨感,对于 js 来说尤是。

不可变与无副作用

不可变与无副作用是函数式的两大特点,但对应到底层就意味着大量的复制。无论是深浅拷贝,拷贝的过程本身就要付出性能代价,而且每一次拷贝还要牺牲对应的空间。现实就是,函数式的库其实现并不能完全实现两者,需要依靠使用者的自觉,这完全是基于性能与抽象之平衡所考虑的。事实上,即使是函数式的语言,也会基于现实与抽象作出抉择。

递归与消失的尾递归

用 js 实现函数式最大的窘迫就在于尾递归的消失,使得递归无法得到优化,从而引起堆栈溢出。虽然理论上用递归实现的,用迭代也能实现,但是一则实现难度不是一个难度了,二则丧失了函数式的明晰性了。

命令式编程的辅料

一个程序本质上是解决问题的,它必然是步骤的罗列,而函数式的理想在于抽象,在纯计算下,它有着出色的表达能力,然而程序不是单纯的计算,程序自身运行就会带有“副作用”。现实中的函数式并不存在,只存在作为命令式编程辅料的函数式,它只是用于改进原来命令式计算之缺陷而被加入到现有的很多命令式语言之中,我们只需要在性能可容许的范围用就可以了。但对于函数式本身来说,除了在理论堆中蜷缩,这样的现实未免过于骨感了。