[squeak-dev] Re: New Window VM (Closures, FT2Plugin, Large Cursors)

Bert Freudenberg bert at freudenbergs.de
Sun Mar 8 18:01:38 UTC 2009


On 08.03.2009, at 18:13, Rob Rothwell wrote:

> On Sun, Mar 8, 2009 at 12:38 PM, Bert Freudenberg <bert at freudenbergs.de 
> > wrote:
>> multiply := Array new: 4.
>> 1 to: 4 do: [:i |
>>        multiply at: i put: [:x | x * i].
>> ].
>>
>> And you would rightfully assume that this is equivalent to the  
>> version above, just more concise. But now try again:
>>
>> (multiply at: 3) value: 5.
>>
>> The answer will, surprisingly, not be 15 in current Squeak.
>
> You are right!  25, in fact...
>
>> But with closures, the blocks would behave as expected. They are  
>> said to "close over" the state that the bound variables (i in this  
>> case) had at the time the block was created.
>
> So...VW does this "right," I guess, since I get 15 in VW NC 7.6?

Yes, it has block closures.

>> So basically, you can use blocks as you always have, but they will  
>> behave as you might have assumed they would.
>>
> So the recent VM work discussed handles this?  I will have to give  
> that a try!
>
> Thanks for the explanation!  The next question, of course, is WHY  
> does it get 25 and not 15... ;)


Because instead of "closing over" the current value of i when the  
block is created, all the blocks share the same reference to i, which  
is actually another temporary variable of the method, instead of being  
local to the block. So when the block is evaluated later, the last  
value of i is used.

Now you might still expect that last value of i to be 4, but actually  
"1 to: 4 do:" is expanded by the compiler to a while loop like "i :=  
1. [i <= 4] whileTrue: [i := i + 1]", so it actually is 5 after the  
loop terminates.

And all this is avoided by having real closures, the i would indeed be  
local to the block and not a shared temp.

- Bert -




More information about the Squeak-dev mailing list