当然,我在扯淡(Surely I Am Joking)· 现站 129 篇公开文章 · 2012 年 5 月 18 日至 2026 年 7 月 15 日,仍在更新 · 产量极不均匀:2013 年一年 30 篇,2023 到 2025 三年一共 4 篇 · 一次明显转折:2016 年 3 月《我为什么不再做 PL 人》之后,主题从程序语言逐渐移向教学、健康与生活 · 标签分布以「哲学」32 篇、「教育」26 篇、「程序语言」24 篇、「AI」18 篇为主 · 全站免费,文末是自愿付费 · 本页通读 16 篇,跨度 2012 年 7 月至 2022 年 2 月,其中 6 篇落在现站最早的 20% 时间段内,2016 年转折两侧均有取样
把王垠现在这个网站上的 129 篇文章全部抓下来,数一数站内互相引用的次数,会得到一个荒诞的结果:被他自己引用最多的两篇文章,都已经不在这个网站上了。六篇指向《编程的智慧》,五篇指向《怎样写一个解释器》;链接还躺在正文里,点开是空的。一个用二十年反复告诉你「要去读原始文献、不要读转述」的人,把自己的原始文献删掉了。
这不是八卦。它恰好落在他一生真正在追的那个问题上:一个想法从发明它的人手里传出去,经过教科书、术语、奖项、传记、师承,传到你手上时,还剩下什么。
他撞上这个问题的那一刻有确切的场景:他去读现代逻辑学的创始论文——Frege 1879 年的《Begriffsschrift》——发现里面一个公式都没有。整篇只有二十多页,画的全是像电路图一样的东西,一根线接一根线,非常好读。今天 PL 论文里那些让人眼花的逻辑符号,是后来的人为了把这些图写成一行才发明的转写。
其实他的目的是用符号来表示那些电路图,结果到后来徒孙们以为那些符号就是祖传秘籍的精髓,忘记了那些符号背后的电路图,所以导致了今天的混乱局面。《我和权威的故事》,2014 年 1 月 4 日
一个便于书写的编码,被后人当成了本体。这是打开整个博客的钥匙,他后来写的几乎所有东西都是它的变形。最原创的那一下是:文本只是编码,结构才是本体。他说得毫不含糊——
代码的本质根本就不是字符串,它本来就是一个具有复杂拓扑的数据结构,就像电路一样。《对 Parser 的误解》,2015 年 9 月 19 日
这句话一旦当真,很多东西会连锁塌方:语法分析几十年的技术,不过是在给人为搞复杂的编码做解码,他称之为「万里长征的第 0 步」;Unix 拿无结构的字符串做进程间通信,是把这个错误刻进了地基。而反过来用,它极好使:万能图灵机说白了就是一个解释器,CPU 也是。2011 年他在 Google 实习,看出那个跨语言代码索引系统「不过是一个抽象解释器」——一个周末做出原型,三个月做完了别人认为要几年的东西。
而他唯一的评判标准是:人的脑子能不能不跳转就装下它。他最好的一次示范是拿 Haskell 的 currying 开刀。(f 2) 比 \y -> f 2 y 短,可是短的那个不告诉你 f 到底要几个参数,你得跑去看定义再跑回来。他把参数加到三个,那个「聪明」写法就变成了 flip (f 1) 2,而「笨」写法还是原样。然后他写下那句可以刻在他墓碑上的话:
有时候,好的程序其实不在于显示你有多「聪明」,而在于显示你有多「笨」。《Currying 的局限性》,2013 年 4 月 2 日
同一把尺子量测试驱动开发:测试是赛道边的护栏,而「护栏并不能让你成为好的车手,不能让你取得冠军」。量他自己的行当,得出那句最狠的自我要求——「真正的天才,必须能够让事情变得简单。」
合起来,他做的始终是同一件事:把一个被反复转述的东西按回它的原始形态,然后报告差异。他用它重算了图灵——Church 的论文比图灵的投稿早一年,模型还更简单;他用它清点了《设计模式》——把二十几个模式映射到自己每天在用的概念上,映射居然是多对一的;他用它拆穿了「超人类机器视觉」——那个基准给机器五次机会猜,而人只需要一次。
最后他把这把刀转向了「天才」这个词本身。2017 年,他公开收回自己几年前写的《怎样成为一个天才》:「我要告诉大家一个秘密:我撒了一个谎。」他说世界上根本不存在天才这种东西,这个概念压根没有定义。论证一如既往地朴素:你说爱因斯坦、费曼、图灵是天才——你跟他们聊过吗?没有。那你脑子里关于他们的一切是哪来的?全是从别人嘴里来的。又是二手知识,又是那条被传抄到变形的链。
刀太快,也会砍到不该砍的地方。2017 年他写下「自动生成程序是根本不可能的事情」,九年后这句话的绝对形式已经站不住;他还把同一套「我自己想清楚了,主流都是错的」用到了近视上——那个领域里,别人的随机对照试验给出了相反的结论。
但他早就替读者写好了免责声明,而且这大概是他写过的最诚实的一句:「我也希望大家都具有批判的思维,不要盲目的接受我说的话。」
王垠的网站现在是一个前后端分离的应用,文章从一个接口里取。这件事有个副作用:你可以把全站 129 篇文章一次性抓下来,然后做一件他自己大概没做过的事——统计站内的互相引用。
结果很干净。引用最多的是《博文的自愿付费方式》,十一次,那是他挂在文末的收款说明,不算。第二名是《编程的智慧》,被六篇引用;第三名是《怎样写一个解释器》,被五篇引用。这两篇是他整个写作的承重墙:谈测试让你去读前者,谈图灵机让你去读后者,谈 Java 的 visitor 模式、谈 Kotlin、谈 Swift,都往这两篇上引。
然后你点开链接,什么也没有。这两个地址今天取不到任何文章。同样消失的还有他写 Dan Friedman 的那篇、写 Chez Scheme 编译器课的那篇。
一个用二十年反复告诉读者「跟真正的大师学习,而不是跟他们的徒弟」的人,亲手删掉了自己被引用最多的原始文献。今天想读它们,只能去读别人转载的、来源不明的副本——也就是他一辈子都在骂的那种东西。这不是用来嘲笑他的事,它恰好落在他一生真正在追的那个问题正中间。
王垠,清华大学计算机系博士生,没读完就走了。临走前他写信给 Knuth 说国内研究环境太浮躁,Knuth 回了一封纸信,回的是:「计算机科学不是每个人都可以做的。如果你试了这么久还不行,那说明你注定不是干这行的料。」后来他到美国,先在康奈尔读了两年博士,被系主任一封塞进信夹子里的纸信请走——他到下学期开学才发现那封信;随后转到印第安纳大学,跟 Dan Friedman 和 Kent Dybvig 学程序语言。中间在 Google 实习两次做出了 PySonar,后来又在 Coverity、Shape Security 写过代码。现在他在中国教计算机科学课。
有一个细节比任何履历都更像他。为了读懂 Knuth,他把 TeXbook 从头到尾看了两遍,做完了所有习题;发现了一些无关紧要的小错,给 Knuth 发邮件,换回两张传说中的「Knuth 支票」。像所有拿到这种支票的人一样,他没去兑现,一直放在原来的信封里。多年以后他到美国想兑现,发现支票已经过期了。
博客还活着但已经换了物种。2013 年他一年发了 30 篇,2023 到 2025 这三年一共 4 篇,其中三篇是课程招生、脚气和近视。最新的两篇是 2026 年 7 月的《如何彻底消灭家里的蚊子》和《我和螨虫的故事》。他现在还在自己的网站首页上挂一份「精选文章」,九篇里有四篇是健康和生活。
f(2,3) 变成「f(2) 返回一个新函数,再喂给它 3」。Haskell、ML 默认这么干。只读他最出名的那些文章,很容易以为他的主题是「骂」:骂 Unix、骂 Go、骂图灵、骂 TDD、骂名校。骂是他的语气,不是他的题目。
他十几年没放下的那个根问题是:一个想法从发明它的人手里传出去,经过教科书、术语、奖项、传记、师承,传到你手上时,还剩下什么?
程序语言领域的论文有一个铁打的规矩:正文里必须有那么一页,排着一堆弯弯曲曲的逻辑符号。做这行的人普遍觉得逻辑学家高人一等,觉得那些符号有「数学的美感」。王垠自己也在这套东西里泡了好几年。
直到有一天他去读了源头:现代逻辑学的创始论文,Gottlob Frege 1879 年的《Begriffsschrift》。他发现那篇论文里一个这样的公式也没有。整篇只有二十多页,画的全是像电路图一样的东西,一根线接一根线,而且——这是他特意写下来的——非常容易读懂。今天那些让人望而生畏的符号,是后来的人(比如 Gentzen)为了把图写成一行而发明的转写方式。
不知道是哪一个后辈把电路图改成了一些稀奇古怪的符号。其实他的目的是用符号来表示那些电路图,结果到后来徒孙们以为那些符号就是祖传秘籍的精髓,忘记了那些符号背后的电路图,所以导致了今天的混乱局面。《我和权威的故事》,2014 年 1 月 4 日
一个为了方便书写而发明的编码,被三代之后的人当成了本体。原来那个可以直接看懂的东西,反而没人记得了。
他后来一次次重新遇到这个形状:链条上某一环做了一次有损的再编码,下游的人把这个副本当成了原件。
他对这件事为什么这么敏感,自己给过一个不太谦虚但大概是真话的解释:「我有非常简单的头脑,我看不懂复杂的公式,听不懂高深的术语。可正是因为这一点,让我脱离了已有理论的困扰。」而权威是这条链上的放大器——他写权威时用的那个比喻,是整个博客里最好的一个:
权威就像广告,它埋伏在你的潜意识里。听一遍不信,听两遍不信,……,直到一千遍的时候,它忽然开始起作用了,而且这作用越来越强。《我和权威的故事》,2014 年 1 月 4 日
下面三个想法,是这同一个根问题在三个方向上长出来的。
2013 年 4 月,他写了一篇很短、看起来最不严肃的文章,标题叫《几个超炫的专业词汇》。内容是他从一位同事的博客上搬来的一组英文黑话,配图,当笑话贴。里面有「Yoda 表示法」(因为 C 语言的 = 和 == 太像,程序员改成把常量写在等号左边)、「先辈的罪」(当时看着合理、回头看很蠢的历史遗留设计)、「Heisenbug」(你一去观察它就消失的 bug)。
其中有一条,他后来用了一辈子:
珍珠是怎么形成的?是由于异物掉进了蛤蚌的外套膜和贝壳之间的夹层里面,没法排出来。……在软件里面也有很多这样的「珍珠」。由于早期的挠人的设计错误,用户不得不采用一些「变通方案」(workaround)或者「附加过程」,这些就像珍珠质一样。久而久之,这些变通方案凝结起来,变成了「软件珍珠」,不了解它们来源的人都视之为宝贝。虽然产生于同样的原理,「软件珍珠」远远没有真正的珍珠那么好看。《几个超炫的专业词汇》,2013 年 4 月 15 日
这篇玩笑文章后来成了他站内被引用第二多的严肃文章。因为「珍珠」不是一个比喻,它是一个诊断程序。看到一个被广泛传授、被引以为豪的技巧,就问一句:这个技巧存在,是在补偿什么地方的设计错误?
他把这个程序跑在了最大的目标上。他十年前写过一篇《完全用 Linux 工作》,在中国 Linux 圈子里红极一时;后来他把整套东西反过来看了一遍。Unix 的世界里,人们以知道各种巧妙用法为荣——而在他看来,那些全是珍珠:
公司里,学校里,充满了因为知道一些 Unix 的「巧妙用法」而引以为豪的人,殊不知他们知道的只是回避一些蹩脚设计的小计俩。程序员有太多的特例和细节需要记忆,不但不抱怨,还引以为豪。《我和权威的故事》,2014 年 1 月 4 日
这里有一个容易被忽略的机制,而它才是这个想法真正锋利的地方:珍珠会自我保护。一旦一套变通办法固化成共同语言,掌握它就成了身份,质疑它就成了没水平。他举的例子极准——Dennis Ritchie 说过「Unix 是简单的,但只有天才才能理解这种简单」:这话一出,你就不敢说 Unix 太复杂,因为说了等于承认自己不够天才。他拿《皇帝的新装》里织布工的话来对照。
同一个诊断程序跑在《设计模式》上,动作干净利落。他那时在康奈尔读博士,好奇这本书为什么名气这么大,从图书馆借了一本回来:
当时我就拿起一张纸,把所有的 20 来个设计模式跟我常用的编程概念做了一个映射。这个映射居然是「多对一」(many-to-one)的。也就是说,多个 GoF 设计模式,居然只对应同一个我每天都用的概念。《解密"设计模式"》,2013 年 3 月 7 日
注意他做了什么:他没有论证,他做了一张映射表然后数了一下。多对一意味着这些名字没有切分出新东西,它们是同一个概念在一种表达力不足的语言里被迫展开成的多种写法。作者们自己的辩护是,他们的贡献就是给这些编程方式起名字,好让广大程序员有共同的语言;他的回应是这个博客的语气标本:如果这也叫贡献,那他也可以写本书,给空气、水、猪肉全都起个新名字。
而这不只是他一家之言:Peter Norvig 1998 年做过一个演讲,指出 GoF 那二十几个模式在动态语言里绝大部分「透明」了——你根本感觉不到它们存在。名字不见了,因为坑不见了。
这是他最原创的一下,也是三个想法里唯一一个不是在拆别人、而是在盖自己东西的。
起点是一个所有程序员都以为自己懂的问题:什么是 parser。2015 年他坐下来专门写了一篇,因为他觉得「大部分人对于 parser 的误解之深,再不澄清一下,恐怕这些谬误就要写进歪曲的历史教科书」。
他的科普是标准的:parser 把 "1+2" 这个字符串转成一个对象。但接下来那句不是标准的,那是一记重锤:
实际上,代码的本质根本就不是字符串,它本来就是一个具有复杂拓扑的数据结构,就像电路一样。「1+2」这个字符串只是对这种数据结构的一种「编码」,就像 ZIP 或者 JPEG 只是对它们压缩的数据的编码一样。《对 Parser 的误解》,2015 年 9 月 19 日
如果这句话当真,一连串东西会塌下来。
首先塌的是一整个研究方向。LL、LR、GLR、LEX、YACC、ANTLR、PEG——几十年的技术积累,在这个视角下全部是解码器的技术,而且是为了解开人们自找的复杂编码而不断加码的技术。他给 parser 起的外号是「万里长征的第 0 步」,因为拿到那棵树之后真正的编译才开始。他的结论毫不留情:「Parser 的研究其实是在解决一些根本不存在或者人为制造的问题。」
顺着塌的是 Unix。Unix 哲学的核心——用无结构的字符串做进程间通信——在这个框架里就是把「编码」当成了「本体」,而且刻进了地基;于是几十年里一切都在补:AWK、sed、Perl、XML、CORBA、JSON。而 Lisp 的设计原则里早就有一条 Do not encode:不要把有用的数据编码进字符串里。
但这个想法真正值钱的地方,是它反过来用的时候。如果本体是结构,那么「理解一个东西」就有了一个可操作的定义:你能不能写出它的解释器。
他把这个还原剂泼向了一切。万能图灵机(UTM)被无数人说成是现代计算机的思想源头,他说:「说白了,UTM 就是一个解释器,就像 Python 或者 JavaScript 的解释器一样。」CPU 是解释器,它解释机器指令。Knuth 那个让他看不懂的 MMIX 处理器模拟程序,他后来明白为什么会看不懂——它就是一个机器代码的解释器,只是 Knuth 用一堆小聪明把这件事盖住了。被 PL 圈奉若神明的 Martin-Löf 类型论,他把 1980 年那篇演讲稿拿出来读了一遍,结论是「通篇本质上就是在讲一个 partial evaluator 要怎么写」。
这不只是说说。2011 年他在 Google 实习,老板 Steve Yegge 要做一个能跨语言精确跳转到定义的代码索引系统,让他去找一个开源的 Python IDE 把语义分析部分挖出来。他看了十个左右,发现没有一个能正确跳转,因为它们做的都是正则表达式匹配。于是:
可是我很清楚的看到,这样一个语义检索,不过是一个抽象解释器 (abstract interpreter)。写解释器是我最在行的,所以我告诉他这是我可以完成的,而且由于设计上的简洁,我的代码的维护代价会比使用一个开源项目小很多。《我和 Google 的故事(2012 年原版)》,2012 年 7 月 12 日
老板不信,说一个小组的高级程序员三个月也做不出来;同组的人打开 JSCompiler,光符号表那一个文件就有九千多行。他那个周末把 Jython 的 parser 拿来,设计了一个更简单的树结构,在上面写了个抽象解释器,星期一就拿出了原型。
这个想法最后落成了他的教学。《解谜计算机科学》从四岁小孩掰手指算 4+3 讲起:你伸出手指,是因为「4」和「3」这两个符号本身不能操作,你得先把它们转成一个可以操作的模型——又是编码与本体。然后他一路讲到计算的定义:
因为计算就是处理信息,信息有它诞生的位置(输入设备,固定数值),它传输的方式(赋值,函数调用,返回值),它被查看的地方(分支)。你想不出对于信息还有什么其它的操作,所以你就很安心的相信了,这就是计算机科学这种「棋类游戏」的全部规则。《解谜计算机科学》,2018 年 4 月 13 日
他对一段代码、一个语言特性、一套工程方法的评价,最后都收敛到同一把尺子上。而这把尺子是他在一个非常小的例子上磨出来的。
2013 年 4 月,他写 currying。Haskell 和 ML 的默认做法是把多参数函数拆成单参数函数的链条,于是「把列表里每个数加 2」可以写成 map (f 2) [1,2,3],比不用 currying 的 map (\y -> f 2 y) [1,2,3] 短一点。所有人都觉得短的那个好。
他要你换一个立场看:
注意,我们现在的「重点」在于你,一个人,而不在于计算机。你仔细想,不要让思维的定势来影响你的判断。《Currying 的局限性》,2013 年 4 月 2 日
从 \y -> f 2 y 里,你一眼看到 f 要两个参数、第一个已经填了 2、第二个等着列表里的元素。从 (f 2) 里你看不到这些。f 可能要两个参数,也可能要三个、四个;如果是三个,map (f 2) [1,2,3] 返回的根本不是数字的列表,而是一串还差一个参数的函数。你必须跑到别处去查 f 的定义,再跑回来。
然后他把参数加到三个,让你把中间那个参数 map 出去。「聪明」的写法变成 map (flip (f 1) 2) [1,2,3],「笨」的写法还是 map (\y -> f 1 y 2) [1,2,3]。
能想出这段代码说明你挺聪明,可是如果你这样写代码,那就是缺乏一些「智慧」。有时候,好的程序其实不在于显示你有多「聪明」,而在于显示你有多「笨」。《Currying 的局限性》,2013 年 4 月 2 日
他自己给出了那个隐藏的判据:「笨」写法对每个参数位置都长一个样,「聪明」写法对每个参数位置都不一样。以不变应万变的那个才是好的。而这段推理里真正可迁移的东西是那个词——「一道弯」。他说 currying 带来的是「直觉上的开销」:如果你不能同时看见这些信息,你的脑子就需要多转一道弯。
此后他几乎所有的工程判断,都是在数这道弯。
测试。他不反对测试,他反对测试变成信仰。他的比喻是赛道护栏:护栏有时候能救命,但一个合格的车手心里想的是更快到达终点,不是护栏。三流车手因为总撞出去,就在心里给护栏至高无上的地位,甚至把护栏摆到赛道中间来确保自己的转弯幅度正确。
护栏并不能让你成为好的车手,不能让你取得冠军。绝大多数时候,你的安全只有靠自己的技术,而不是护栏,你永远有办法可以撞死自己。《测试的道理》,2016 年 9 月 14 日
而他列出的十二条里,最硬的那几条全都是「弯」的账。为了能 mock 而给每个类配一个 interface,代价是你按 F12 不再能跳到实现,得先跳到接口再找实现——「这种方便性的损失,会大幅度降低头脑产生整体理解的机会。」测试实现细节而不是测试性质,本质上是「把代码写了两遍」,于是「每当要修改代码,你就得修改两次」。而「每修一个 bug 就配一个测试」这条公司铁律,他给的是一个正确的反问:这个 bug 有多大可能在同一个地方再次发生?低级疏忽一旦被看出来,下次通常会换个地方发生,而那里没有测试。
小语言。你看到 foo(x, y + z),不认识 foo 也知道会发生什么,因为你对函数调用已有心理模型;而在一个新造的 DSL 里 foo 可能是个循环,模型作废,你必须去读文档。所以他把它写成一条戒律:「不到万不得已的时候,千万不要制造语言。」这恰恰和 PL 人的专长相矛盾,所以「有原则的 PL 人,生活怎么可能不苦」。
这篇文章是 2016 年 3 月的《我为什么不再做 PL 人》,也是这个博客的分水岭。他在里面把自己待了十年的领域拆得很彻底:问题要么二十年前就解决了、要么像停机问题一样不可能解决,可是博士毕业要求你发表「创新」,于是只能炒冷饭;论文里那些逻辑公式看透了就是解释器的代码,只不过用一种晦涩的语言写出来,而且没有 debugger,所以「逻辑学家们成天为自己的设计失误和 bug 伤透了脑筋,PL 专家们却认为他们具有数学的美感」。最后他给这一节收了个尾,那句话同时是他对自己的要求和对整个行业的判决:
这些所谓天才,看不到简单直观的解决方案,为了显示自己的聪明而采用繁复的抽象,其实是一种愚蠢。真正的天才,必须能够让事情变得简单。《我为什么不再做 PL 人》,2016 年 3 月 31 日
读长期写作者,可迁移的往往不是结论而是动作。他的动作有四个,都很具体,都可以拿去用。而它们共同的特征是:能数就数,不辩论——数字不一定让他对,但它让他的错误可以被别人查出来。
第一,把「不理解」当成对方的问题,先去查源头。绝大多数人看不懂 TAOCP、看不懂计算理论教材、看不懂 PL 论文的公式,结论是「我不够聪明」;他的结论是「让我去看看这东西最早是什么样的」。于是他读到了 Frege 的原论文、Church 1936 年那篇两页纸的 note、Martin-Löf 1980 年的演讲稿、Neil Jones 那本用普通程序语言重讲全部计算理论的书。他给这条动作起过名字:「跟真正的大师学习,而不是跟他们的徒弟。」
第二,用「你能把它实现出来吗」当作理解的验收标准。他引过一位数学家的话:为了真正深入地理解一个东西,你应该把它写成程序。这既是他的方法,也是他攻击整个学术圈的武器——逻辑语言「只运行于逻辑学家的脑子里面」,写出来的东西一样有 bug,而且没有 debugger。
第三,拿一个最小的具体例子当撬棍。他几乎从不用抽象论证开场。想说「超人类机器视觉」是假的,他不谈基准的方法论,他告诉你那个基准叫 Top-5:机器每张图可以说五个名字,猜中一个就算对。
这就像设计一个考试,每道选择题本来只有一个正确答案,但却给了 5 次机会做对。这样就没法分清优等生和差等生了,甚至差等生有时候表现比优等生还好,因为不确切知道答案,瞎蒙都能做对。《"超人类机器视觉"是不存在的》,2021 年 7 月 29 日
他还补了一刀,而这一刀是有名有姓的:当年那个「人类对照组」只有一个人,而且不是外请的独立实验者,是项目组自己的学生。然后他把这条抽象的批评接到地上——在路上把卡车认成白板是会死人的,而人在真实环境里没有五次机会。
第四,怀疑名字,而且怀疑到底。在他的框架里,一个新名字的出现通常意味着链条上又发生了一次再编码。他对 AI 领域给出过一个刻薄但值得记住的规律:
人工智能的研究者们似乎很喜欢制造吓人的名词,当人们对一个名词失去信心,他们就会提出一个不大一样的,新的名词,免得人们把对这个名词的失望,转移到新的研究上面。然而这些名词之间,终究是换汤不换药。《人工智能的局限性》,2017 年 4 月 23 日
这条路走到尽头,是 2017 年那篇《天才是不存在的》。传记作者靠「天才」这个词吃饭,同僚靠它沾光——「一传十,十传百,到时候大家都认为他是天才的时候,你就是天才的同学了」——对手则靠它打击你。他给出的结论是八个字:「天才出于勤奋,而且天才出于政治。」
这四个动作有一个共同的形状,也有一个共同的代价:它们全都是单人作业——一个人读源头,一个人实现,一个人数,一个人下判断。他在《我和权威的故事》里承认了这个代价,语气罕见地平静:「创造力和孤独几乎是双胞胎。」
他的方法有一个结构性的缺口:它只有一个观察者。回到源头、亲手实现、自己数一遍,全都在他一个人脑子里闭环。面对程序语言这种「写出来跑一下就知道」的对象时,这个闭环极其强大;一旦对象变了,它就没有刹车。
第一,被时间直接否掉的那个预言。2017 年的《人工智能的局限性》里,他写:
任何一个负责的程序语言专家都会告诉你,自动生成程序是根本不可能的事情。……因为「读心术」是不可能实现的,所以要机器做事,人必须至少告诉机器自己「想要什么」,然而表达这个「想要什么」的难度,其实跟编程几乎是一样的。《人工智能的局限性》,2017 年 4 月 23 日
这段话里的两层命运完全不同。下面那层活得很好:把需求说清楚的难度确实接近编程本身,这几乎就是今天每个跟模型结对写代码的人日常在经历的事。上面那层错了,错在他最喜欢的那种绝对句式上——他当时判断的对象是微软 RobustFill 那类从少量例子归纳程序的玩具系统,从那个样本推出「根本不可能」,是把技术上限当成了原理上限。
第二,同一把刀用在医学上,结果不一样。这是他自己挂在网站首页「精选文章」里的:九篇精选有四篇是健康和生活,其中 2022 年的《自然视力恢复法》主张配一副比实际度数低 100 度的眼镜一直戴着,如此循环直到视力恢复 1.0;参考资料只有两项——W. H. Bates 1920 年那本《不戴眼镜的完美视力》和一个 YouTube 讲座。可这个领域有人做过随机对照试验,结论是相反的:Chung、Mohidin、O'Leary 2002 年发在《Vision Research》上的研究,把 94 名 9 到 14 岁近视儿童随机分成欠矫约 0.75D 与足矫两组跟踪两年,论文标题本身就是结论——《欠矫加速而非抑制近视进展》;世界小儿眼科与斜视学会 2023 年的共识声明也不再推荐欠矫。
值得注意的是失效的具体位置。他用的还是那套动作:自己想清原理、回到源头、不信主流。但在程序语言里,「回到源头」意味着回到 Frege 和 Church——那是原理,写下来就能验证;在近视这件事上,它意味着回到一位一百年前的医生,而这一百年里真正能判定对错的东西,恰恰是他从不使用的那类证据:多人、随机、对照、可重复。他的方法里没有「别人做过实验」这一环,因为在他原来的领域里不需要这一环。
第三,他把动机当事实来写。《图灵的光环》里时间线和文献那部分扎实,可他还告诉你图灵「心高气傲,恐怕从来没把 Church 当成过老师,反倒总觉得 Church 抢先一步,破坏了自己名垂青史的机会」——这是心理描写,不是史料。他批评《图灵传》作者片面使用对图灵有利的证据,而他自己对图灵、对 Knuth、对 Go 的设计者,用的是同一手法的镜像。
第四,也是最实际的一条:他的东西没法核对。他不做同行评议,很少引用,而且会删文。回到开头那个统计——今天你想检验《编程的智慧》或《怎样写一个解释器》到底说了什么,只能去读别人转载的、来源不明的副本。他给自己的读者造出了一条他毕生批判的那种链条。
至于中文技术圈对他的争论,大多散落在知乎、CSDN 和各种论坛转帖里。我没有找到一篇有分量、可引用的技术性反驳原文,所以这里不复述任何我没读过的论证。
而最狠的那条批评是他自己写下的。《我和权威的故事》结尾,在把 Knuth、Unix、常青藤、图灵奖挨个轰下神坛之后,他加了一句:
我深深地知道接受错误想法的危害性,所以我也希望大家都具有批判的思维,不要盲目的接受我说的话。我不喜欢「大神」或者「牛人」这种称呼,我也反感那种自称膜拜我的人,因为正是这种人让权威主义现在横行于世。《我和权威的故事》,2014 年 1 月 4 日
这是读这个博客唯一正确的用法,而且是他本人开的处方。