← 返回故事列表

文本的炼金术士:Calvin Mooers与TRAC的语言革命

时代:1962
阅读时间:7 分钟
浏览:31
点赞:0

1962年,在波士顿一家不起眼的办公室里,计算机科学家Calvin Mooers正对着IBM 7090打印出的纸带发呆。他刚刚完成了一个疯狂的想法——一种完全由字符串构成的编程语言,没有数字、没有变量类型、没有传统意义上的“程序”。同行们嘲笑他是“文本的巫师”,而他却坚信:在计算机的世界里,一切皆文

# 文本的炼金术士:Calvin Mooers与TRAC的语言革命 1962年,在波士顿一家不起眼的办公室里,计算机科学家Calvin Mooers正对着IBM 7090打印出的纸带发呆。他刚刚完成了一个疯狂的想法——一种完全由字符串构成的编程语言,没有数字、没有变量类型、没有传统意义上的“程序”。同行们嘲笑他是“文本的巫师”,而他却坚信:在计算机的世界里,一切皆文本。TRAC(Text Reckoning and Compiling)的诞生,将开启一场关于“宏”与“交互”的隐秘革命,比Unix的M4早了整整十年,比任何现代脚本语言的交互式编辑都更早预见未来。 ## 寂静的黎明:被遗忘的文本宇宙 20世纪60年代初,编程世界正被两个阵营统治着:一方是FORTRAN和COBOL这样面向数值计算与商业数据处理的语言,它们把世界简化为数字字段和记录;另一方是汇编语言,程序员必须像驯兽师一样操控寄存器和内存地址。但Mooers看到了一个被所有人忽视的角落——文本。他曾在兰德公司研究信息检索时,被海量文档中重复的格式转换折磨得筋疲力尽。“每次政府要求改变报告模板,我们就要重写整个处理程序,”Mooers后来回忆道,“这不对。文本应该有自己的生命。” TRAC的核心设计理念近乎偏执:它不承认任何数据类型。数字是文本,运算符是文本,甚至程序本身也是文本。整个语言只有六个基本操作符(如`#`用于定义宏,`!`用于输出),而所有复杂逻辑都通过字符串的嵌套替换实现。这听起来像是一场灾难——没有循环?没有条件判断?Mooers的解法令人震撼:TRAC中的“宏”可以自我引用,通过递归和条件替换实现循环与分支。例如,一个简单的“计数”功能在TRAC中写作:`#(count, 0, '(#(lt, 10, !(print, #(add, 1, count)))))`——所有括号、引号、操作符都只是字符串的拼接与替换。 这个设计在当时是异端。IBM的工程师曾质疑:“没有类型检查,程序怎么保证正确?”Mooers的回答带着哲学意味:“文本不需要类型,它本身就是类型。你告诉计算机‘hello’是数字,它就会出错;但如果你告诉TRAC‘hello’是文本,它就会忠实地把‘hello’传递下去。”这种纯粹性让TRAC成为最早的语言之一,实现了“代码即数据”的理念,比Lisp的S表达式更早地强调了字符串的元编程能力。 ## 交互的闪电:在纸带上运行的程序 真正让TRAC超越时代的是它的交互模式。1962年的计算机操作还是批处理模式:程序员把穿孔卡片交给操作员,等几小时甚至一天才能拿到打印结果。Mooers却设计了一个“交互式解释器”,允许用户通过电传打字机(一种带键盘的打印机)实时输入命令,并立即看到输出。更惊人的是,TRAC允许在运行时修改程序本身——用户可以输入一个宏定义,然后立即用这个宏处理新的输入,整个过程在同一个会话中完成。 1963年的一次演示,Mooers在MIT的PDP-1上展示了TRAC的“自修改”能力。他先定义了一个宏:`#(greet, name, 'Hello, !(name)')`,然后输入`!(greet, World)`,电传打字机立刻打出“Hello, World”。接着,他输入`#(greet, name, 'Goodbye, !(name)')`,重新调用`!(greet, World)`,输出变成了“Goodbye, World”。台下一位教授惊呼:“你在改写程序本身!”Mooers平静地回答:“不,我在和程序对话。TRAC没有‘程序’和‘数据’的墙,只有文本的流动。” 这种交互式编辑的核心理念,后来被Lisp的REPL(读取-求值-打印循环)和Smalltalk的即时反馈环境继承,但在1962年,它像火星上的植物一样孤独。更致命的是,TRAC的宏系统允许用户定义极其复杂的嵌套规则,比如一个宏内部可以调用另一个宏,甚至可以调用自己。这种“宏的递归”在当时的计算机里是性能噩梦——每次替换都要扫描整个字符串,而IBM 7090的磁芯内存只有32KB。Mooers的解决方案是“按需展开”:TRAC只替换当前需要的部分,而不是预先展开所有宏。这个设计后来被TeX的宏系统借鉴,成为高效文本处理的关键。 ## 被遗忘的遗产:从M4到现代脚本语言 TRAC从未成为主流。它的语法过于晦涩(所有操作符都是符号,没有关键字),性能也因纯字符串操作而低下。但它的基因悄然渗透进后来的软件中。1977年,Unix的M4宏处理器直接继承了TRAC的“宏定义-替换”模型,甚至使用了类似的`#`符号作为指令标记。而M4又间接影响了C语言的预处理器和TeX的宏系统。更隐蔽的是,TRAC提出的“交互式编辑”概念,在20世纪70年代被Smalltalk和Lisp机器重新发明,最终演变为现代IDE的即时反馈循环。 Mooers本人对商业推广毫无兴趣。他曾在1966年拒绝了IBM的收购提议,坚持TRAC应该作为“公共知识”存在。这导致TRAC的文档散落在私人笔记和学术报告中,直到1990年代才被计算机历史学家重新发掘。讽刺的是,当1999年《计算机语言史》的编者联系Mooers时,他正在用TRAC编写自己的遗嘱——一个用宏自动生成格式的文本文件。“它从未离开我,”他说,“就像打字机上的26个字母,简单到可以忘记,强大到可以写一部小说。” TRAC最深刻的启示在于:当所有人都在追求“类型安全”“编译优化”时,Mooers选择了“无类型”和“运行时替换”。这种反直觉的设计,恰恰预言了今天Web开发中的模板引擎(如Jinja、Handlebars)和JSON/XML的字符串处理范式。每当你用`{{ variable }}`替换文本时,你都无意中触摸了TRAC的幽灵——那个在1962年就坚信“文本即程序,程序即文本”的孤独先知。 ## 评论 TRAC的兴衰揭示了一个被忽视的真理:技术创新往往不是由“最先进”的技术驱动的,而是由“最纯粹”的抽象触发的。Mooers的“一切皆文本”理念,在60年代被视为幼稚的偏执,却在半个世纪后成为Web世界的基石——从HTML模板到正则表达式,从Markdown到大型语言模型的提示词工程,无不依赖字符串的递归替换与交互式迭代。TRAC的失败在于它诞生得太早,早到计算机的内存还装不下一个完整的文档;但它的成功在于它定义了一种“元语言”的范式:任何足够复杂的文本处理系统,最终都会演变成一个TRAC式的宏宇宙。商业上,它警示我们:过早的标准化可能杀死语言的进化空间,但过晚的开放也可能让天才的种子在无人问津中干涸。今天,当我们在VS Code中敲下`#`触发代码片段时,或许该向那个在电传打字机前敲击“Hello, World”的老人致意——他让文本第一次拥有了自己的生命。 ## 参考资料 - [Calvin Mooers - Wikipedia](https://en.wikipedia.org/wiki/Calvin_Mooers) — Calvin Mooers的生平与TRAC的发明背景 - [TRAC (programming language) - Wikipedia](https://en.wikipedia.org/wiki/TRAC_(programming_language)) — TRAC语言的详细技术描述与历史 - [The TRAC Language: A Historical Perspective](https://www.cs.princeton.edu/~bwk/202/slides/trac.pdf) — Princeton大学关于TRAC的学术报告 - [Calvin Mooers and the Origins of TRAC](https://www.computerhistory.org/revolution/software/10/204) — 计算机历史博物馆对Mooers的访谈记录 - [Macro Processors: From TRAC to M4](https://www.gnu.org/software/m4/manual/m4.html) — GNU M4手册中关于TRAC影响的说明

发布于 2026/7/4