9

我是 Smalltalk 的新手,是在 Squeak 中学习的。但是我发现 Smalltalk 中有很多令人困惑的地方。在Squeak,MetaClassMetaClass class互为对方的班级。如果我想创建对象MetaClass,我应该向它的类发送一条消息new,即MetaClass class. 但它必须首先作为对象存在才能接受消息。所以我必须先创建对象MetaClass class,这只能通过向尚未创建new的对象发送消息来完成。MetaClass所以这是一个先有鸡还是先有蛋的问题。

当然我现在可以在 Squeak 中创建对象,因为MetaClassMetaClass class对象已经在 Squeak 打开时自动创建。但我不知道怎么做。也许它们是通过发送消息以某种方式创建的。但它与 Smalltalk 的精神相矛盾:除了少数几点(变量声明、赋值、返回和原语)之外,一切都是通过发送消息来发生的。

上面的推理有问题吗?提前致谢。

4

3 回答 3

13

你的问题是双重的,让我们分别回答。

如何创建相互依赖的类?

您是对的,Metaclass并且Metaclass class是 Smalltalk 类和元类的并行层次结构中的一个奇点。它们是如何创建的?

这取决于您使用的 Smalltalk。对于 GNU Smalltalk,我不确定,但对于原始 Smalltalk-80(VisualWorks,VA aka VisualAge,SqueakPharo)的后代,它们是在创建初始图像的引导过程中创建的。

然而,至少对于 Squeak 来说,这种引导至少发生在 15 年前,如果不是更久的话。Metaclass它的班级甚至可能长达30年。

长话短说,这两个类都是在典型的图像处理之外创建并手动链接在一起的。

但如果这些物体是多年前的,这就引出了一个问题

Smalltalk 的创业公司会发生什么?

与 Ruby 或 Python 等面向对象的语言相反,Smalltalk 不需要Object在每次启动时都创建一个基本的对象环境。为什么?

当 Smalltalk 保存并关闭时,它基本上会对其所有对象进行快照并将这些活动对象保存到文件中。当它再次启动时,它只需要从快照中读取对象并“恢复”它们。

因此,对于MetaclassMetaclass class,两个对象都是从快照中读取并恢复的,从这一点开始,它们是完全正常的;它们不再需要手动创建。

于 2013-06-18T20:04:45.067 回答
12

“自动创建”的过程实际上称为bootstrapping。鸡和蛋的问题就是这样解决的。一旦系统被引导,所有其余的都可以用系统本身来表示。因此,Smalltalk 的哲学并不矛盾,即一切都是通过发送消息发生的,因为它只有在启动后才成为 Smalltalk 系统。

于 2013-06-18T20:07:51.453 回答
9

Metaclass class class = Metaclass是奇怪循环的经典学术例子。但是,如果您稍微询问一下,您可以在 Smalltalk 中找到许多其他的。

  • 对象超类是 nil ,它是 UndefinedObject 的一个实例,它是 Object 的子类(通过 Squeak 中的 ProtoObject 的更长链Object superclass superclass class superclass = Object
  • MethodDictionary 的方法存储在 MethodDictionary ( MethodDictionary methodDictionary class = MethodDictionary) 的一个实例中。
  • Symbol 的名称是 Symbol 的一个实例(与 Squeak 中的 ByteSymbol 一起使用ByteSymbol name class = ByteSymbol)。
  • ArrayedCollection 的子类存储在 Array 的一个实例中,该实例是 ArrayedCollection ( Array superclass subclasses class = Array) 的子类。
  • Smalltalk 是一个 SystemDictionary,它通过#Smalltalk 键指向 Smalltalk(这在 Squeak 中不太直接,(Smalltalk globals at: #Smalltalk) = Smalltalk)。

我让你自己继续列表。

无论实施如何,最终的问题是您是否可以设计一个像 Smalltalk 这样没有这些奇怪循环的自描述系统,如果您关注http://en.wikipedia.org的子链接,您可能会看到一个不太肯定的答案/wiki/Kurt_G%C3%B6del#The_Incompleteness_Theorem

与此类系统遇到的引导程序问题相关,一种有效的方法是克隆自己以更改自己,当您想要更改用于更改/描述类的基类时,在 Smalltalk 映像中尤其如此。
因此,我之前的简洁答案是通过应用规则的字母(https://stackoverflow.com/help/deleted-answers)而不是我认为的精神删除的:

以下是解决方法: http ://en.wikipedia.org/wiki/Drawing_Hands

最后一点,我更愿意阅读Smalltalk 的难以置信的一致性,但我绝对有偏见。

于 2013-06-19T19:43:04.527 回答