如何在幕后实现Smalltalk的whileTrue消息?

时间:2009-01-27 21:49:26

标签: smalltalk

我正在努力教自己Smalltalk。 A tutorial有一个while循环的例子:

|i| 
i:=5. 
[i >0] whileTrue:[ 
 Transcript show: ((i*2) asString) ; cr. 
 i:=i-1. 
].

据我了解,whileTrue是发送给BlockClosure的消息,只要接收方为真,就告诉接收BlockClosure运行作为参数给出的BlockClosure。

如果没有Smalltalk中的while循环结构,BlockClosure响应的whileTrue消息是如何实现的?或者它是用运行时编写的任何语言实现的?

3 个答案:

答案 0 :(得分:6)

在我的VisualWorks图像中,它是通过递归完成的:

whileTrue: aBlock

   ^self value
      ifTrue:
      [aBlock value.
      [self value] whileTrue: [aBlock value]]

但是,还有一个注释,如果接收器和参数都是文字块,编译器将内联一个#whileTrue:call。因此,在大多数情况下,您还可以考虑#whileTrue:看起来像语法上发送的消息的“神奇”消息之一,但实际上已经优化为不同的字节码。

答案 1 :(得分:0)

根据this forum whileTrue不是真实的消息。

答案 2 :(得分:0)

如前所述:编译器在我已知的所有实现中作弊和内联。因此,实际上不需要在正常情况下存在该方法,并且通常不会调用该方法。 但是,在不实际使用编译器的情况下执行或解释动态生成的代码结构时,该方法可能很有用。

顺便说一下,由于Smalltalk语言标准(实际上并不存在)并不强制实现消除尾部调用(例如,与Scheme相反),因此VW中的递归实现对于执行或解释(除非编译器作弊是标准化的)。

没有递归的替代方案可能是:

whileTrue:aBlock
    self value ifFalse:[^ nil].
    aBlock value.
    thisContext restart