艾伦·凯谈"面向对象编程"的含义 (2003年)
摘要
2003年艾伦·凯的电子邮件阐明了"面向对象编程"的原始含义——以消息传递、数据隐藏和生物学/细胞隐喻为中心,最初有意省略了继承。
暂无内容
查看缓存全文
缓存时间: 2026/06/30 06:34
# 艾伦·凯博士谈“面向对象编程”的含义 | 因果导向架构笔记
来源:https://notes.shixiangxi.com/en/docs/appendix/alan-kay-on-oop/
以下是艾伦·凯于2003年7月发给斯特凡·拉姆的两封邮件,澄清了“面向对象编程”最初对术语创造者而言的含义。
**来源:**http://www.purl.org/stefan_ram/pub/doc_kay_oop_en
---
## 邮件1 —— 2003年7月23日 (https://notes.shixiangxi.com/en/docs/appendix/alan-kay-on-oop/#email-1--july-23-2003)
> **主题:**回复:澄清“面向对象”
嗨,斯特凡——
抱歉回复晚了,我一直在度假。
2003年7月17日下午6:27 \+0200,斯特凡·拉姆写道:
> 尊敬的凯博士,我希望在我的教程页面中引用一些关于“面向对象编程”这一术语的权威说法。我认为唯一权威的来源是国际标准化组织(ISO),它在“ISO/IEC 2382-15”中定义了“面向对象”,以及您本人——因为据称您是这一术语的创造者。
我相当确定是我创造的。
> 遗憾的是,很难找到一个网页或第一手来源包含您对该术语的定义或描述。有一些关于您可能就此说过什么的报道(比如“继承、多态和封装”),但这些都不是第一手资料。我也知道后来您更强调“消息传递”——但我仍然想了解“面向对象”的本意。为了记录、我的教程页面以及进一步的分发和出版,您能否解释一下:“面向对象”这一术语最早是在何时何地使用的?
大概是在1966年11月之后的某个时候,在犹他大学,受到Sketchpad、Simula、ARPAnet的设计、巴勒斯B5000以及我在生物学和数学方面的背景影响,我想出了一种编程架构。很可能是在1967年,有人问我在做什么,我回答说:“这是面向对象编程。”
最初的构想包含以下几个部分。
- 我认为对象就像生物细胞或网络上的独立计算机,只能通过消息进行通信(因此消息传递从一开始就存在——花了一段时间才找到如何在编程语言中高效实现消息传递的方法)。
- 我想摆脱数据。B5000通过其几乎令人难以置信的硬件架构几乎做到了这一点。我意识到细胞/整台计算机的隐喻可以摆脱数据,并且`<-`只是另一个消息令牌(我花了不少时间思考这个问题,因为我原本把所有符号都视为函数和过程的名称)。
- 我的数学背景让我意识到每个对象可以关联多个代数结构,并且可以有这些结构的家族,这将非常非常有用。“多态”这个术语是后来(我想是彼得·韦格纳)强加的,它并不完全恰当,因为它实际上来自函数的命名法,而我想要比函数更多的东西。我创造了一个术语“泛型”(genericity)来处理准代数形式的泛型行为。
- 我不喜欢Simula I或Simula 67实现继承的方式(尽管我认为Nygaard和Dahl是了不起的思想家和设计者)。所以我决定暂时不将继承作为内置特性,直到我更好地理解它。
我最初关于这种架构的实验是通过一个模型进行的,该模型改编自范维恩加滕和沃斯的“Algol的推广”以及沃斯的Euler。两者都相当类似LISP,但语法更传统、更易读。我当时没有理解LISP那种有形的元语言概念,但通过从各种来源(包括Irons的IMP)汲取的可扩展语言思想,我算是接近了。
第二阶段是最终理解LISP,然后利用这种理解来构建更优美、更小巧、更强大、更晚绑定的底层结构。Dave Fisher的论文采用了“McCarthy”风格,他关于可扩展控制结构的思想非常有帮助。另一个重要影响来自Carl Hewitt的PLANNER(它从未得到应有的认可,考虑到它比Prolog更早且更好地预见到了Prolog)。
Xerox PARC最初的Smalltalk就源于上述工作。后续的Smalltalk在历史章节的结尾处受到了批评:它们向Simula倒退,并且没有将扩展机制替换为同样有用的更安全机制。
> “面向对象[编程]”对您来说意味着什么?(不需要教程式的介绍,只需用其他概念简要解释一下[比如“通过继承、多态和封装编程”],供熟悉这些概念的读者理解。另外,没有必要解释“对象”,因为我已经有您从“Smalltalk早期历史”中对“对象”的解释来源。)
(我不反对类型,但我不知道有任何类型系统不是完全令人痛苦的,所以我仍然喜欢动态类型。)
**对我而言,OOP仅仅意味着消息传递、局部保留和保护以及隐藏状态过程,以及所有事物的极端晚绑定。**可以在Smalltalk和LISP中实现。可能还有其他系统也能做到这一点,但我对此并不了解。
Cheers,
Alan
---
## 邮件2 —— 2003年7月26日 (https://notes.shixiangxi.com/en/docs/appendix/alan-kay-on-oop/#email-2--july-26-2003)
> **主题:**回复:澄清“面向对象”
我本应提及的一点是,Simula催生了两条主要路径。早期的那条(纯属偶然)是我走的生物/网络非数据-过程路线。另一条稍晚一些,作为研究对象的是抽象数据类型,这条路获得了更多的关注。
纵观整个历史,我们看到原始OOP的东西始于ADT,然后有一个小小的分支走向了我所谓的“对象”——导致了Smalltalk等——但在那个小分支之后,计算机科学界基本上都在做ADT,并希望坚持数据-过程范式。从历史角度看,值得关注的是美国空军巴勒斯220文件系统(我在Smalltalk历史中描述过)、道格·罗斯在MIT的早期工作(AED及更早)——他倡导将过程指针嵌入数据结构、Sketchpad(具有完全的多态性——例如,其数据结构中的相同偏移量意味着“显示”,并且会有一个指向适当例程的指针,用于该结构所代表的对象类型等),以及巴勒斯B5000,其程序引用表是真正的“大对象”,包含指向“数据”和“过程”的指针,但如果在试图访问数据时遇到过程指针,通常也能做出正确反应。而且,我早期在犹他州解决的最初问题就是“数据的消失”——只使用方法和对象。在60年代末(我想),Bob Balzer写了一篇非常精彩的论文,题为“无数据编程”,不久之后,John Reynolds也写了一篇同样精彩的论文“Gedanken”(我想是在1970年),其中他展示了正确使用lambda表达式可以让过程抽象出数据。
喜欢将对象视为非数据的人较少,包括我自己、Carl Hewitt、Dave Reed以及少数其他人——这个群体几乎全部来自ARPA社区,并以某种方式参与了ARPAnet->Internet的设计,其中计算的基本单元是一整台计算机。但为了展示一个想法可以多么顽固地持续存在,在整个七十年代和八十年代,有许多人试图使用“远程过程调用”来替代思考对象和消息。Sic transit gloria mundi(尘世荣耀转瞬即逝)。
Cheers,
Alan
> **2003年7月26日晚上10:05 \+0200,斯特凡·拉姆写道:**
> 2003年7月23日星期三上午9:33:31\-0800,Alan Kay写道:
> 对我而言,OOP仅仅意味着消息传递、局部保留和保护以及隐藏状态过程,以及所有事物的极端晚绑定。
> 嗨,Alan,我只想对您的解释(包括上面未引用的部分)说声“谢谢”!在OOP的背景下,“局部保留”对我来说是一个新概念,我假设它指的是状态过程,意味着对象拥有其状态过程,因此对象的状态与对象一起局部保留,而不是在其他地方。我已经将您的回复发布在网络上,但为了保护隐私,删除了电子邮件地址和类似的头部行。再次感谢,Stefan
---
## 要点总结 (https://notes.shixiangxi.com/en/docs/appendix/alan-kay-on-oop/#takeaway)
对于艾伦·凯而言,面向对象编程从来都不是主要关于继承、类或封装本身。它关乎的是:
- **消息传递** 在独立实体之间
- **局部保留和保护** 状态过程
- **极端晚绑定** 所有事物
这也是为什么因果导向架构认为传统的对象即数据容器模型具有局限性:当对象被简化为带有方法的状态包时,消息传递、自治计算单元这一更深层次的思想就会丢失——随之而去的,还有随时间推移对因果进行清晰建模的方法。
相似文章
一封给面向对象的情书
一篇论证面向对象编程的真正本质是消息传递而非类,并介绍了Abject项目和Ask协议,作为对这一思想在AI领域的复兴的文章。
@PandaTalk8: 几年前, 遇到一个文科生的神人。 他问我面向对象是什么, 我说是一种抽象,给他讲了一大堆, 类, 继承,多态之类的概念。 最后他若有所思, 原来你说的就是分类啊。 他这个回复把震惊了,原来一直都没有搞懂真相的是我, 事实上还真的就是分类的…
A tweet shares a personal anecdote about explaining object-oriented programming to a humanities student, who insightfully summarized it as 'classification', leading the author to discover applied category theory and a related course.
面向切面编程的回归
一篇重新审视面向切面编程的博客文章,讨论了程序员必须管理的众多横切关注点,如正确性、日志记录和安全性。
面向观察的编程:我如何围绕*观察*而非*执行*组织终端AI智能体集群
一位开发者详细介绍了观察导向编程(OOP),这是一种围绕观察可观测性数据而非任务执行来组织终端AI智能体群体的范式。该系统使用tmux、cron、bash和仅追加日志文件,智能体充当观察者,关联信号并仅在解释后才能具体化行动。
迈向可理解的软件
本文批判了当前的编程实践和对大语言模型的依赖,反而主张通过更好的抽象、文档和软件栈来使代码更易于理解和维护。