1992年底,Alan Kay坐在三万五千英尺高空的机舱里,膝上放着一台重5磅、售价低于700美元的笔记本电脑。机器拥有高分辨率位图屏、重叠窗口和无线网络选项,他在上面运行着自己当年设计的Smalltalk。

表面上看,二十多年前他在施乐PARC构想的手持认知媒介Dynabook已经变成了现实货架上的工业品。但在1993年正式刊登于《ACM SIGPLAN Notices》的长文《The Early History of Smalltalk》里,这位图灵奖得主写下的判断却极度克制:从数量级上看,它超越了当年的构想;但从质的维度来看,它还远远没有抵达终点。

大众普遍把Smalltalk当成被乔布斯借走图形界面的技术先驱,以为面向对象就是后来教科书里背诵的封装、继承和多态。这其实是一场持续半个世纪的买椟还珠:今天我们使用的个人电脑和工业软件,只继承了当年为了性能妥协留下的外壳,却把最核心的活体计算介质丢得一干二净。

一页纸的赌约与没有继承的原生混沌

计算机在1960年代的主流形态是大型机与批处理,程序意味着一串静态指令对内存数据的单向操作。Alan Kay的思考起点完全不同:受生物学中受精卵分裂和细胞互动的启发,他认为计算机不该被切分成脆弱的数据结构与过程,而应该由无数个行为自洽的通用细胞组成。每个细胞包裹着自己的状态,只通过消息传递彼此沟通。

早期 Smalltalk 像相互通信的独立活细胞,不设固定继承树(示意图)
早期 Smalltalk 像相互通信的独立活细胞,不设固定继承树(示意图)

1972年9月,Kay在施乐PARC立下一个著名的赌注:能否在一页纸代码内写出一个具备完整能力的语言解释器。Dan Ingalls随即在Data General NOVA小型机上用BASIC实现了Smalltalk-72的核心消息传递解释器。同年11月22日,Kay在MIT人工智能实验室演示了这一解释模型,直接激发了Carl Hewitt提出早期的Actor并发模型。

计算隐喻的分水岭:冯诺依曼机器 vs 生物学细胞 传统大型机 / 过程式思维 • 核心逻辑:数据结构 + 过程控制 • 执行方式:指令对被动内存的强力修改 • 系统形态:自上而下的批处理与分立程序 • 局限:系统规模膨胀导致复杂度失控 Smalltalk / 活体计算思维 • 核心逻辑:离散细胞与纯粹消息交互 • 执行方式:自治个体协商,极端晚期绑定 • 系统形态:完全自描述的单体交互介质 • 突破:如生物组织般无限生长与自修复

今天很多工程师难以想象的是,被奉为面向对象圭臬的Smalltalk-72根本没有内置类继承机制。它没有固定的语法树,甚至没有区分操作系统和应用程序。每个对象接收到一段消息流,就自主解析后续的标记。系统依靠这种动态求值机制模拟一切,极其自由,但也极度缓慢。

1973年4月,Chuck Thacker造出了第一台Alto工作站原型机,施乐团队称其为Interim Dynabook。Smalltalk在这个硬件上实现了自举运行,成为整台电脑唯一的交互环境。为了解决性能泥潭,1974年推出的Smalltalk-74(又称FastTalk)集成了微代码化的bitblt图形渲染原语,并引入了面向对象虚拟内存管理系统OOZE,这才让这套动态介质能在有限的硬件内存里撑起复杂的交互界面。

烧掉磁盘组:向现实性能妥协的Smalltalk-76

早期的极端自由很快撞上了现实的高墙。受蒙台梭利与布鲁纳认知理论启发的LRG团队,本想为儿童打造探索工具,但施乐内部逐渐要求系统承担企业级数据库、文档排版与商业仿真任务。未受约束的动态消息流在面对复杂工程时变得脆弱不堪。

重构后的系统确立严格继承机制,以规范秩序换取工程效率(示意图)
重构后的系统确立严格继承机制,以规范秩序换取工程效率(示意图)

1976年1月,团队在Pajaro Dunes会议上发出了烧掉我们的磁盘组的宣言。Alan Kay启动了NoteTaker便携硬件研发,而Dan Ingalls则主导了对语言的彻底重构。

Smalltalk 演进轨迹:从动态自由到工程规范 1972 Smalltalk-72 一页纸解释器 无继承 / 纯消息 1974 Smalltalk-74 bitblt 原语 OOZE 虚拟内存 1976 Smalltalk-76 首创字节码执行 正式引入类继承 1980 Smalltalk-80 向工业界公开发布 奠定现代GUI底座

从1976年11月开始,Ingalls历经约7个月将系统从头重写。新系统只有约50个类、180页源码。正是为了换取可预测的执行效率与代码组织度,Smalltalk-76首次引入了字节码编译执行,并且第一次把源自Simula的严格继承机制固化为语言核心。

我们今天以为理所当然的类继承,实际上是先驱们向现实计算资源妥协的产物。

这次重写换来了惊人的工程可用性。1978年1月的施乐管理层测试中,10位高管中有9位在完全没有专业编程背景的情况下,只借助Smalltalk-76构建的SimKit套件就独立完成了复杂的企业仿真系统搭建。但代价同样明确:动态消息传递的绝对自主权被收拢,分类阶级秩序自此确立。


走偏的工业界:从生物隐喻到内存排布

真正让技术轨迹发生永久分道扬镳的,是1979年Bjarne Stroustrup启动的C with Classes项目。Stroustrup面临的是贝尔实验室的系统级资源受限环境,他没有选择Smalltalk那种耗费算力的动态查找与纯消息路由,而是倒向了Simula 67:用编译期静态类型来锁定内存布局,将方法调用压缩成固定的指针偏移或虚函数表跳转。

工业界将面向对象锁定在静态内存中,背离了原本的活体计算(示意图)
工业界将面向对象锁定在静态内存中,背离了原本的活体计算(示意图)

软件工业在接下来的四十年里做出了冷酷而务实的抉择。C++和随后的Java拿下了工业界的主导权,面向对象被简化成了内存对齐、强类型签名与继承树。正如Kay后来反复痛惜的那样:我很抱歉造出了面向对象这个词,因为它让所有人都把注意力放在了对象上,而真正关键的是它们之间的消息传递与极端晚期绑定。

两条演进路径的价值取向对照 主流工业栈(C++ / Java) • 绑定时机:编译期早期绑定,静态类型 • 调度实质:内存偏移调用,消灭路由开销 • 核心诉求:**机器执行效率与资源受限控制** PARC 原教旨(Smalltalk) • 绑定时机:运行时晚期绑定,完全反射 • 调度实质:对象间独立协商,保留容错可能 • 核心诉求:**人类心智延展与活体交互介质**
  • 结论.Smalltalk并没有在商业世界里死去,它只是化整为零,以特洛伊木马的方式潜伏进了整个现代软件世界:Objective-C借用其语法支撑起早期的iOS生态,MVC架构成为了现代Web的骨架,字节码虚拟机演化为JVM和V8引擎,而即时修改状态的镜像机制则变成了今天Jupyter Notebook和交互式调试器的底色。
  • 风险.但这场胜利丢失了灵魂。在现代操作系统里,用户面对的是一个个固化封闭的应用孤岛,必须在文件保存、进程重启和死板的数据格式之间来回搬运,当年的计算环境从可交互的活体介质退化成了死气沉沉的数字打字机。

在AI大模型重构编程范式的今天,静态类型正在重新暴露出表达刚性的瓶颈,而允许即时自省、自修改代码以及高度晚期绑定的活体环境,再度展现出极具诱惑的弹性。重读三十年前Kay在高空机舱里的这篇反思,并不是在沉湎复古情怀;它是提醒我们,如今被我们当作计算常识的一切规则,不过是当年工业妥协留下的一处偏狭支流。真正的山顶,我们其实还没有去过。