上个月刷到一篇《A Friendly Introduction to Racket》,8 月 11 号发的,geometridae 的 bearblog。转它的是个写后端的同行,平时连 Haskell 都不点开。他转的理由是开头那句——Eric S. Raymond,学 Lisp 会有深刻的启蒙体验。
我看完第一反应:这套开场白我见过。
文章讲,1958 年 McCarthy 在 MIT 搞出 Lisp,是现役高层语言里第二老的,只比 1957 年的 Fortran 晚一年。Python 要到 1991,JavaScript 要到 1995。中间差了三十多年。
它列了一串 Lisp 首创或普及的东西:垃圾回收、一等函数、REPL、条件语句当表达式、同像性。
我数了一下,这五样里只有一样是救过命的。
垃圾回收。
剩下那四样,在凌晨三点的生产环境里,多数时候是给你添活的。不是说它们没价值——说句实话,有一堆烂不是设计蠢,是用错了地方、接手的人不够。但活是我接。
一等函数写起来是真爽。它也是回调地狱的源头。传进去传出来,出了错翻栈,全是匿名函数,谁调的你都不知道。
同像性更微妙。代码和数据能互换,写语言的场景里这是神技。放到一套跑了七八年的业务系统里,它多出来一层意思:线上跑的那份代码,在展开之前根本不是你看到的样子。
宏这玩意儿我在一套没人敢碰的祖传系统上吃过亏。grep 一个字符串,grep 不到——它还没被展开。改一行定义,展开出三十行。写它的人早走了,接手的三个人谁也不敢动。
那篇文章里还有个 define-syntax-rule 定义 while 循环的例子,三行搞定,写得很干净。我盯着那儿看了半天,想到的全是上面那套东西。
Racket 的招牌就是"用于构建语言的语言",非正式座右铭叫"面向语言的编程"——问题需要专属语言,你花几天造一个出来。
听着很美。
工程上的版本是:一个团队人人会造 DSL,最后你手上有二十种 DSL,每种只有一个作者懂。这是造屎山的高速通道,还是 VIP 口。
扯远了。
真正让我服气的不是那串特性清单,是它讲 Lisp 机器那一段。七十到八十年代,Symbolics 和 LMI 造过专门跑 Lisp 的硬件,一家公司就指着这个吃饭。然后 AI 冬天来了,钱断了,Lisp 从主流明星掉成小众语言。
写得很克制,一笔带过。但这一段是完整剧本,我这几年看了不止一遍。
一个东西被宣布是未来。资本进来。专门的硬件,专门的公司,专门的人才盘子全建起来。然后钱一断,整条链子一夜之间没了。
技术没死。死的是靠它吃饭的那批人。
Lisp 后来去哪儿了?跑到 Emacs 里——几百万人每天在不知情的情况下跑着 Emacs Lisp,因为他们的编辑器本身就是个 Lisp 解释器。Nubank,拉美最大的那家数字银行,整套跑在 Clojure 上。还有 Common Lisp 加 SBCL 撑着的一些飞行规划老系统,ITA Software 被 Google 收了之后还在给 Google Flights 干活。Guix 拿 Scheme 配了一整个 Linux 发行版。Racket 自己也没闲着,Rosette 做形式验证,Pollen 做排版出版,每年还开个 RacketCon。
都是不吆喝的东西。
顺便说 Racket 的来历。1975 年 Sussman 和 Steele 搞出 Scheme,极简、优雅,成了学术界教编程的首选,SICP 就是拿它写的。1995 年 Felleisen 那拨人在 PLT 做了 PLT Scheme,2010 年改名 Racket。
Scheme 那段我每次看到都想补一刀。"极简优雅"这四个字放到生产里,往往意味着什么都得自己造,最后自己造出来的东西比语言本身复杂十倍。学术界爱它是对的,学生从零开始,需要的是干净的语义,不是现成的地基。
还有个细节,文章引了 Alan Kay 那句"Lisp 是软件的麦克斯韦方程组"。这种话听着动人。但麦克斯韦方程组不会在半夜三点把你那条限流配置顺手搞没,也不会在你 grep 不到东西的时候给你解释为什么。
对了,文章末尾有个彩蛋——某部动画里一个角色打开终端,屏幕上行文件名是 Caine-core.lisp。花边。但它说明一件事:Lisp 在文化记忆里的位置,比它在招聘启事上的位置稳。
那篇文章推荐的资源我看了下:SICP、《How to Design Programs》、《The Racket Guide》、《Beautiful Racket》。书单正经,没有"三天精通"之流。
同像性它用 '(+ 1 2) 演示:带引号返回列表,first 拿出来是 +,丢给 eval 才是 3。例子干净,教学上没毛病。
但看懂这个例子,和看懂一套用宏堆起来的祖传 DSL,中间隔着一条产业级的沟。前者是学原理,后者是给人擦屁股。而且你 grep 不到那个屁股。
说回往生产团队推 Racket 这事。你要真在团队里推这种"能造语言"的东西,先把规矩立了:谁造的谁写 runbook,写明它展开成什么、断点打哪儿、出问题怎么绕。将来接手的新人不会感谢你的优雅——他只会在 pager 响的时候先骂一句。
那篇文章最有价值的其实是最后那个意思:Lisp 活到今天,靠的是它不争头条,它在工具链底下干活。活得久的东西都这样。Fennel 编译到 Lua,在游戏圈活得挺好;Hy 干脆跑在 Python 上面。换皮不换骨,但它确实还活着。
所以值不值得学?值得。DrRacket 装一下,定义区第一行 #lang racket,下面 REPL 里敲 (+ 1 2) 看它出 3,raco 管包和工具,这套路径干净,半小时能上手。SICP 该读。
但你别指望它救你的生产环境。
救不了。它自己都差点没活过 AI 冬天。
能救你的,还是你半夜爬起来看日志那点本事。
