Clement,

I am not sure, but could this not be a compiler issue ? 
Not with Opal but with the old compiler ?!

I mean, if you look at the implementations of OrderedCollection>>#do: and 
OrderedCollection>>#collect: they basically do the same thing, going from 
firstIndex to lastIndex, both of which are instance variables, but in the first 
case, the #do:, the end test is evaluated on each iteration, while in the 
second case, the #to:do:, the end test should be evaluated only once. Since 
lastIndex changes while iterating, one iteration sees it, the other not.

Looking at the byte codes seems to confirm that: the compilation of the #:to:do 
is different: Opal correctly moves both instance variables to temps, while the 
old compiler keeps on referring to the second instance variable (lastIndex) 
directly on each loop - which is plain wrong IMHO.

I am with Marcus that you should not modify a collection that you iterate over. 
What if you would be inserting values at arbitrary places ? 

I am with you that both (all) enumerations should be consistent. Like in VW, 
delegating to the simplest #do: seems best.

Sven

On 03 Sep 2014, at 11:42, Clément Bera <[email protected]> wrote:

> Hello guys,
> 
> I was looking into the OrderedCollection protocols recently to see how well 
> the sista optimizer perform with it methods, and I realized that this is 
> completely broken.
> 
> For example:
> 
> col := #(1 2 3 4 5) asOrderedCollection.
> col do: [ :elem | elem trace .
>       elem < 4 ifTrue: [ col add: col size + 1 ]].
> 
> => '12345678'
> 
> However:
> 
> col := #(1 2 3 4 5) asOrderedCollection.
> col collect: [ :elem | elem trace .
>       elem < 4 ifTrue: [ col add: col size + 1 ]].
> 
> => '12345'
> 
> This means that #do: and #reverseDo: iterate over all the elements of the 
> collection,*including* the ones that you are adding while iterating over the 
> collection, whereas all the other OrderedCollection protocols, such as 
> #collect:, #select:, iterates over all the elements of the collection, 
> *excluding* the ones you are adding while iterating over the collection.
> 
> Marcus argued that one should not edit a collection while iterating over it, 
> however this point is not valid as the World menu relies on this feature, 
> using #do: to iterate over the elements of the OrderedCollection including 
> the one it is adding while iterating over the collection. Changing the 
> implementation makes the world menu display half of its items.
> 
> I don't like this difference because it is inconsistent. For example, 
> refactoring a #do: into a #collect: can simply not work because they do not 
> iterate over the same elements if you are editing the collection while 
> iterating over it.
> 
> In VW, the protocols are consistent and iterating over a collection never 
> iterates over the elements one is adding while iterating over it. Therefore, 
> I believe most frameworks should expect this behavior (at least the ones 
> cross smalltalk) which sounds the most correct.
> 
> I think we should fix the world menu implementation and make the protocols 
> consistent. Alternatively, we can let VW be a much more consistent Smalltalk 
> environment than Pharo. What do you think ?
> 
> Clement
> 


Reply via email to