Perfect!<br><br>Thanks...sorry for missing that the two were the same...<br><br>Rob<br><br><div class="gmail_quote">On Sun, Mar 8, 2009 at 6:47 PM, Andreas Raab <span dir="ltr"><<a href="mailto:andreas.raab@gmx.de">andreas.raab@gmx.de</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">That is the bug Eliot was referring to earlier. The loop variable in optimized to:do: loops wasn't handled correctly. Try this instead:<div class="im">
<br>
<br>
multiply := Array new: 4.<br>
(1 to: 4) do: [:i |<br>
multiply at: i put: [:x | x * i].<br>
].<br>
<br></div>
Note the parens around "1 to: 4" which prevents the block from being optimized.<br>
<br>
Cheers,<br>
- Andreas<br>
<br>
<br>
Rob Rothwell wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div class="im">
Ok...thanks...this is making sense!<br>
<br>
So...should I get the "right answer" with the new VM and the 3.10.2-Closures image?<br>
<br>
Because...I still get 25!<br>
<br>
Rob<br>
<br></div><div class="im">
On Sun, Mar 8, 2009 at 2:01 PM, Bert Freudenberg <<a href="mailto:bert@freudenbergs.de" target="_blank">bert@freudenbergs.de</a> <mailto:<a href="mailto:bert@freudenbergs.de" target="_blank">bert@freudenbergs.de</a>>> wrote:<br>
<br>
On 08.03.2009, at 18:13, Rob Rothwell wrote:<br>
<br>
On Sun, Mar 8, 2009 at 12:38 PM, Bert Freudenberg<br></div><div><div></div><div class="h5">
<<a href="mailto:bert@freudenbergs.de" target="_blank">bert@freudenbergs.de</a> <mailto:<a href="mailto:bert@freudenbergs.de" target="_blank">bert@freudenbergs.de</a>>> wrote:<br>
<br>
multiply := Array new: 4.<br>
1 to: 4 do: [:i |<br>
multiply at: i put: [:x | x * i].<br>
].<br>
<br>
And you would rightfully assume that this is equivalent to<br>
the version above, just more concise. But now try again:<br>
<br>
(multiply at: 3) value: 5.<br>
<br>
The answer will, surprisingly, not be 15 in current Squeak.<br>
<br>
<br>
You are right! 25, in fact...<br>
<br>
But with closures, the blocks would behave as expected. They<br>
are said to "close over" the state that the bound variables<br>
(i in this case) had at the time the block was created.<br>
<br>
<br>
So...VW does this "right," I guess, since I get 15 in VW NC 7.6?<br>
<br>
<br>
Yes, it has block closures.<br>
<br>
<br>
So basically, you can use blocks as you always have, but<br>
they will behave as you might have assumed they would.<br>
<br>
So the recent VM work discussed handles this? I will have to<br>
give that a try!<br>
<br>
Thanks for the explanation! The next question, of course, is<br>
WHY does it get 25 and not 15... ;)<br>
<br>
<br>
<br>
Because instead of "closing over" the current value of i when the<br>
block is created, all the blocks share the same reference to i,<br>
which is actually another temporary variable of the method, instead<br>
of being local to the block. So when the block is evaluated later,<br>
the last value of i is used.<br>
<br>
Now you might still expect that last value of i to be 4, but<br>
actually "1 to: 4 do:" is expanded by the compiler to a while loop<br>
like "i := 1. [i <= 4] whileTrue: [i := i + 1]", so it actually is 5<br>
after the loop terminates.<br>
<br>
And all this is avoided by having real closures, the i would indeed<br>
be local to the block and not a shared temp.<br>
<br>
- Bert -<br>
<br>
<br>
<br>
<br></div></div>
------------------------------------------------------------------------<br>
<br>
<br>
</blockquote>
<br>
<br>
</blockquote></div><br>