Reputation: 5314
I am trying to teach myself Smalltalk. A tutorial has this example of a while loop:
|i|
i:=5.
[i >0] whileTrue:[
Transcript show: ((i*2) asString) ; cr.
i:=i-1.
].
As I understand it, whileTrue is a message sent to a BlockClosure, telling the receiving BlockClosure to run the BlockClosure given as the argument as long as the receiver is true.
How is the whileTrue message that BlockClosure responds to implemented without a while loop construct in Smalltalk? Or is it implemented in whatever language the run-time is written in?
Upvotes: 2
Views: 10018
Reputation: 3200
As already mentioned: the compiler cheats and inlines in all implementations known to me. So there is not really a need for the method to be present in normal situations and it is usually not invoked. The method might be useful however, when performing or interpreting dynamically generated code-structures without actually using the compiler.
By the way, as the Smalltalk language standard (which does not really exist) does not force implementations to be tail-call-eliminating (in contrast to Scheme, for example), the recursive implementation in VW is not really useful for performing or interpretation (unless the compiler-cheat is standardized).
An alternative without recursion could be:
whileTrue:aBlock
self value ifFalse:[^ nil].
aBlock value.
thisContext restart
Upvotes: 0
Reputation: 24458
In my VisualWorks image, it's done with recursion:
whileTrue: aBlock ^self value ifTrue: [aBlock value. [self value] whileTrue: [aBlock value]]
However, there's also a note to the effect that the compiler will inline a #whileTrue: call if both the receiver and argument are literal blocks. So in most cases, you can also consider #whileTrue: one of the "magic" messages that looks like a message send syntactically, but is really optimized into different bytecodes under the hood.
Upvotes: 8