In message 034b01c4d7e1$e00d7bd0$3fe22641@antssoftware.com "Joshua Scholar" jscholar@access4less.net wrote:
Your example would NOT see the new elements because SequenceableCollection>>do: is implemented as:
do: aBlock "Refer to the comment in Collection|do:." 1 to: self size do: [:index | aBlock value: (self at: index)]
See, end of the array was computed before the loop started.
If you shortened the array, you would have an error pop up.
Ah, run the code and see what fun it causes. I guarantee you'll see new elements, though they may not be ones you expect. Welcome to... The Become Zone!
"become:" affecting an active iteration is wrong. Iterations can only be clean if they're over a snapshot not over a live collection anyway. Ok, we can't afford pure cleanness but there's no point in pushing the language toward an idiom that can't even be defined without contradictions.
I'm not championing anything here except realism about how much mess one can trivially (and usually unexpectedly) get into when trying to think of optimisations like this. As you say, to be 'safe' one has to somehow lock the collection but I'm not convinced there is actually a real way to do that. And the performance hit could be appalling.
What if "become:" changes the type of array to a different type?
You could argue that an array of a different size IS a different type. It is in many languages.
No, THERE IS NOTHING WRONG locking down the array and iterating over it. If the code calls "become:" then continuting the iteration over the old array is no worse than trying to continue a loop over the new (I would say "wrong") object.
Err, using become: makes the new array into the original one - that's the whole point of become:, after all.
In fact, finishing the iteration with the object you started with _is_ _cleaner_.
If you don't agree with me on that, then maybe you'll decide that _it_ _doesn't_ matter_ _because_ _code_ _shouldn't_ _call_ _become_ _inside_ _of_ _and_ _iterator_ _on_ _that_ _object_.
Well of course I agree with that - but you cannot enforce it in any way that I can think of that would be practical. You cannot restrict the effects of code called during the iteration, nor code running in other threads that might run during the iteration.
I've only been doing this thinking about optimising Smalltalk for a few years so I could be wrong of course. I'm sure there are at least a couple of people alive that have been doing it for longer.
tim -- Tim Rowledge, tim@sumeru.stanford.edu, http://sumeru.stanford.edu/tim Strange OpCodes: FSRA: Forms Skip and Run-Away