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 >
