住在平面国的程序员 (The programmers who live in Flatland)

 

导读:本文翻译自 Nathan Marz 的博客《The programmers who live in Flatland》。作者巧妙地借用科幻小说《平面国》的比喻,探讨了为什么像 Lisp/Clojure 这样具备“更高维度”抽象能力(如宏)的语言,虽然极其强大,却始终难以被主流程序员广泛接受。很多时候,当我们对一种陌生的编程范式感到排斥时,也许正是因为我们试图用二维的视角去理解三维的世界。

在《平面国》(Flatland) 这本书中,一个叫“平面国”的二维世界居住着三角形、正方形和圆形等生物。主角是一个正方形,他被来自第三维度的球体造访。他很难理解另一个维度的存在,即使球体向他展示了不可能的事情。这是一本很棒的书,自从我差不多30年前第一次读它以来,它就一直留在我的脑海里。

我意识到“平面国”是大量程序员思维状态的完美比喻。思考一下:2001年,科技界最具影响力的声音之一 Paul Graham 写了一篇名为《战胜平庸》(Beating the Averages) 的文章。他有力地论证了 Lisp 在根本上比其他语言更强大,并将 Lisp 视为他的初创公司 Viaweb 比竞争对手活得更久的关键原因。他将宏 (macros) 视为 Lisp 尤为与众不同的能力。他写道:

我们很大一部分代码正在做其他语言很难做到的事情。由此产生的软件做到了竞争对手的软件做不到的事情。也许这其中有某种联系。我鼓励你顺着这条线索去思考。

我确实顺着这条线索去思考了,那篇文章也是 Clojure 成为我过去15年主要编程语言的关键原因。Paul Graham 描述的关于宏的威力绝对是真实的。然而显然,很少有人分享我的好奇心,Lisp/Clojure 在全球程序员中的使用率极低。怎么会这样呢?

许多人指出“生态系统”是障碍,这个论点对 Common Lisp 有效,但对 Clojure 无效,因为 Clojure 可以轻松地与现存最大的生态系统之一进行互操作。如此多的误解占据了主导地位,尤其是人们会条件反射地认为括号很“奇怪”。最重要的是,你几乎从未看到这些感知到的成本被用来权衡 Clojure 的巨大优势。宏是这篇文章的重点,但 Clojure 处理状态和身份的方法也具有变革性。Clojure 优势的规模让其被采用的规模相形见绌。

在那篇文章中,Paul Graham 引入了“Blub 悖论”来解释这种脱节。这是一个很棒的比喻,我这些年来多次引用过。这篇文章是我从另一个补充 Blub 悖论的角度来解释这种脱节的看法。

我承认,过去五十年来,Lisp 程序员一直试图传达它的威力,但收效甚微。所以我并不认为我能改变任何人的想法。然而,我还是忍不住写了这篇文章,因为“平面国”这个比喻实在是太贴切了。

编程的维度

编程围绕着抽象展开,这是一种关于代码的高层思维方式,远离了位元、机器指令和内存层级这些底层基础原语。但并非所有的抽象都是生来平等的。程序员使用的大多数抽象都是自动化——一个将一组操作打包在一个名称背后的程序包。函数就是典型的例子:它接收输入并产生输出。你不需要知道函数内部是如何运作的,只需要思考函数的规范和性能特征即可。

还有一些罕见的抽象,它们扩展了编程本身的代数:可用的基本概念以及它们之间可能存在的关系种类。这些是创造新维度的抽象。

Lisp/Clojure 的宏源于语言的统一性,使其能够将语言重新组合到自身之上。在编译时运行逻辑与在运行时运行没有区别,使用的都是相同的函数和技术。可以随意操作和转换语言的语法树,从而能够控制代码本身的语义。这种毫不费力地操纵编译时的能力,是编程的一个新维度。这个新维度使你能够编写出在低维度中永远无法实现的、根本上更好的代码。

如果你已经是一名 Lisp 程序员,你已经理解了宏的威力以及如何避免潜在的陷阱。我的描述很无聊,因为你已经做过一千次了。但如果你不是 Lisp 程序员,我所描述的听起来可能很疯狂且不明智!

在平面国中,正方形无法理解第三维度,因为他只能用二维来思考。同样,你无法理解一个新的编程维度,因为你不知道如何在那个维度中思考。你没有表示机制来理解新维度到底提供了什么。处于二维的程序员可能会得出结论:三维概念客观上是错误的。这并不是因为他们理解了它,而是因为他们试图将它扁平化到自己现有的坐标系中。

学习新维度

你无法用三维的论点去说服一个处于二维的人。这完全就像在《平面国》中,球体无法让正方形理解什么是“上”和“下”一样。

然而,这就是比喻失效的地方。虽然你的大脑永远无法理解四维空间,但你的大脑可以适应编程的新维度。采用 Lisp/Clojure 的人通常会以类似的方式描述这种体验。首先是不舒服,然后是一系列豁然开朗的时刻,最后是感觉自己再也回不去了。

这所需要的只是好奇心,以及理解最伟大的编程理念有时在一开始是无法被欣赏的。后一点是在对话中往往被丢失的关键洞察。我们都有那种认知偏差。认识到这种偏差足以打破它,这也是作为一个程序员成长的最好方法之一。宏并不是唯一具有这种维度转换特征的伟大编程理念。

结论

最后,生活在平面国是一个选择。当你注意到对一个陌生想法本能地退缩时,当你感到“这说不通”和“也许我还没有理解它的概念”之间的紧张感时,这个选择就出现了。你在那一刻所做的事情,定义了你是留在平面国,还是走出去。