Reputation: 59
result := String new.
1 to: 10 do: [:n | result := result, n printString, ’ ’].
Everything in smalltalk is an object and the objects interact through messages.
I couldn't understand how the above code is understanding the message to:do:
How is it able to iterate the block from 1 to 10? How does it know it has to repeat the block that many number of times?
Can someone explain what happens under the hood?
Upvotes: 3
Views: 199
Reputation: 14858
Consider the method
m
1 to: 10 do: [:i | self doSomethingWith: i]
Here are the bytecodes that Pharo generates
pushConstant: 1 ; i := 1
popIntoTemp: 0 ;
@2: pushTemp: 0 ; i <= 10 ?
pushConstant: 10 ;
send #'<=' ;
jumpFalse: @1 ; if false, go to end
self ; self doSomethingWith: i
pushTemp: 0 ;
send #doSomethingWith: ;
pop ;
pushTemp: 0 ; i := i + 1
pushConstant: 1 ;
send #'+' ;
popIntoTemp: 0 ;
jumpTo: @2 ; loop
@1: returnSelf
As you can see the message #to:do
is never sent, while #'<='
and #+
are (even though they are not in the source code!). Why? Because of what Bert said in his answer: these messages are optimized by the Smalltalk compiler. In the case of Pharo the optimization happens in #to:do:
. In other dialects #to:do:
is implemented in terms of #whileTrue:
, which is the one that gets optimized.
Once you have understood how this works under the hood, get back to think of it as if #to:do:
were a regular message with receiver 1
and arguments 10
and the block [:i | self doSomethingWith: i]
. The optimization shouldn't obscure the semantics that your mind needs to follow.
Upvotes: 1
Reputation: 4623
All Smalltalk messages follow the pattern <receiver> <message>.
. In this case the receiver is 1
(a subinstance of Number
), and the message is to:do:
.
You can browse class Number
and see the implementation of to:do:
right there:
to: stop do: aBlock
| nextValue |
nextValue := self.
[nextValue <= stop]
whileTrue:
[aBlock value: nextValue.
nextValue := nextValue + 1]
In your example, stop
is 10
and aBlock
is [:n | result := result, n printString, ’ ’]
. So indeed, it is sending value:
to aBlock
repeatedly.
Now, in addition to that, many Smalltalks generate special byte code when they see the for:to:
message, but this is just an optimization.
Upvotes: 8