<div dir="ltr"><div>Chris Muller wrote in another thread:</div><div><br></div><div>
> There was another change to earlier today that you may be interested<br>
> in asking that question about too, since it changed 19-year old<br>
> SequenceableCollection>>#= with a one-day old replacement and actually<br>
> went into trunk.</div><div><span class="m_-3382998359924029073gmail-im"><br></span></div><div><span class="m_-3382998359924029073gmail-im">Please note that this has been discussed more than a month ago, and the discussion clearly converged to this consensus:</span></div><div><span class="m_-3382998359924029073gmail-im">- having Interval and Array being = is not an important feature</span></div><div><span class="m_-3382998359924029073gmail-im">- it seriously impacts efficiency of Interval hash</span></div><div><span class="m_-3382998359924029073gmail-im">- it causes long standing bugs that we carry for years (19 years or so)</span></div><div><span class="m_-3382998359924029073gmail-im"><br></span></div><div><span class="m_-3382998359924029073gmail-im">What's the point of having Interval = Array, when we have OrderedCollection ~= Array at the same time?<br></span></div><div><span class="m_-3382998359924029073gmail-im">A less arbitrary feature would be a generalization of eachOperand isSequenceable ==> testThatElementsAreSameSequence:</span></div><div><span class="m_-3382998359924029073gmail-im">But it's both too hard to maintain (a bug factory), aand a problem for efficient implementation of some specialized collection.</span></div><div><span class="m_-3382998359924029073gmail-im">At the end, it's maybe not so much a desirable feature and it's practically not used in trunk images, apart for writing shorter tests.<br></span></div><div><span class="m_-3382998359924029073gmail-im">
</span><div><span class="m_-3382998359924029073gmail-im"></span></div><div><span class="m_-3382998359924029073gmail-im">I'm not a big fan of C motto when used with extremism: you don't pay for what you don't buy.</span></div><div><span class="m_-3382998359924029073gmail-im">But I have the feeling that it makes sense here.<br></span></div>

</div><div><br></div><div><span class="m_-3382998359924029073gmail-im">BTW, I don't like 
hasEqualElements: because I mentally associate elements to Set, and for me #(1 2 3) 
hasEqualElements: #(3 1 2), just with a different order.<br></span></div><div><span class="m_-3382998359924029073gmail-im">I would prefer something like isSameSequenceAs: which clearly tells about the ordering.<br></span></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le mer. 13 févr. 2019 à 17:21, Chris Cunningham <<a href="mailto:cunningham.cb@gmail.com" target="_blank">cunningham.cb@gmail.com</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Thank you. This was an angle I hadn't thought of - but definitely opens up how to fix it correctly:<div><i>>Definitively abandon SequenceableCollection equality tests based on equal species. </i> <br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Feb 12, 2019 at 2:56 PM <<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Nicolas Cellier uploaded a new version of Collections to project The Trunk:<br>
<a href="http://source.squeak.org/trunk/Collections-nice.820.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/trunk/Collections-nice.820.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Collections-nice.820<br>
Author: nice<br>
Time: 12 February 2019, 11:56:35.262017 pm<br>
UUID: bb383133-067c-4133-987b-c481a7de69c7<br>
Ancestors: Collections-ul.819, Collections-cbc.813<br>
<br>
Definitively abandon SequenceableCollection equality tests based on equal species.<br>
<br>
Old behaviour can still be obtained thru hasEqualElements: but the default is to not try to support such trans-class equality feature because it is much too complex.<br>
<br>
Particularly Interval are no more equal to Arrays with same sequence. We can thus optimize hash a bit more and fix the old bugs of equa objects with different hashes. Merge Collections-cbc.813 for this and rehashAll in postscript.<br>
<br>
There are not so many classes concerned by this change, mainly RunArray, Interval and LinkedList:<br>
<br>
Collection withAllSubclasses select: [:e | [e basicNew species ~= e] on: Error do: [false]]<br>
-> an OrderedCollection(WeakRegistry LinkedList Interval ByteCharacterSet CharacterSetComplement LazyCharacterSet WideCharacterSet ShortRunArray Semaphore Mutex TextLineInterval WeakArray Monitor MCVersionName ByteSymbol WideSymbol)<br>
<br>
We will have to change the tests that rely on such equality.<br>
<br>
=============== Diff against Collections-ul.819 ===============<br>
<br>
Item was changed:<br>
  ----- Method: FloatArray>>= (in category 'comparing') -----<br>
  = aFloatArray <br>
-       | length |<br>
        <primitive: 'primitiveEqual' module: 'FloatArrayPlugin'><br>
+       ^super = aFloatArray!<br>
-       aFloatArray class = self class ifFalse: [^ false].<br>
-       length := self size.<br>
-       length = aFloatArray size ifFalse: [^ false].<br>
-       1 to: self size do: [:i | (self at: i)<br>
-                       = (aFloatArray at: i) ifFalse: [^ false]].<br>
-       ^ true!<br>
<br>
Item was changed:<br>
  ----- Method: Interval>>= (in category 'comparing') -----<br>
  = anObject<br>
- <br>
        ^ self == anObject<br>
+               or: [anObject isInterval<br>
+                       ifFalse: [super = anObject]<br>
+                       ifTrue: <br>
+                               [start = anObject first<br>
+                                and: [step = anObject increment<br>
+                                and: [self last = anObject last]]]]!<br>
-               ifTrue: [true]<br>
-               ifFalse: [anObject isInterval<br>
-                       ifTrue: [start = anObject first<br>
-                               and: [step = anObject increment<br>
-                                       and: [self last = anObject last]]]<br>
-                       ifFalse: [super = anObject]]!<br>
<br>
Item was changed:<br>
  ----- Method: Interval>>hash (in category 'comparing') -----<br>
  hash<br>
        "Hash is reimplemented because = is implemented."<br>
+         ^((start hash hashMultiply bitXor: self last hash) hashMultiply<br>
+                 bitXor: self size)!<br>
- <br>
-       ^(((start hash bitShift: 2)<br>
-               bitOr: stop hash)<br>
-               bitShift: 1)<br>
-               bitOr: self size!<br>
<br>
Item was changed:<br>
  ----- Method: RunArray>>= (in category 'comparing') -----<br>
  = anObject <br>
+       self == anObject ifTrue: [^ true].<br>
-       "Test if all my elements are equal to those of anObject"<br>
- <br>
        ^anObject class == self class<br>
+               and:<br>
-               ifTrue: "Faster test between two RunArrays"<br>
                        [(runs hasEqualElements: anObject runs)<br>
+                        and: [values hasEqualElements: anObject values]]!<br>
-                        and: [values hasEqualElements: anObject values]]<br>
-               ifFalse:<br>
-                       [anObject isCollection and: [self hasEqualElements: anObject]]!<br>
<br>
Item was changed:<br>
  ----- Method: SequenceableCollection>>= (in category 'comparing') -----<br>
  = otherCollection <br>
        "Answer true if the receiver is equivalent to the otherCollection.<br>
+       First test for identity, then rule out different class and sizes of<br>
-       First test for identity, then rule out different species and sizes of<br>
        collections. As a last resort, examine each element of the receiver<br>
        and the otherCollection."<br>
<br>
        self == otherCollection ifTrue: [^ true].<br>
+       self class == otherCollection class ifFalse: [^ false].<br>
-       self species == otherCollection species ifFalse: [^ false].<br>
        ^ self hasEqualElements: otherCollection!<br>
<br>
Item was changed:<br>
  ----- Method: Symbol>>= (in category 'comparing') -----<br>
  = aSymbol<br>
        "Compare the receiver and aSymbol." <br>
        self == aSymbol ifTrue: [^ true].<br>
+       aSymbol isSymbol ifTrue: [^ false].<br>
-       self class == aSymbol class ifTrue: [^ false].<br>
        "Use String comparison otherwise"<br>
        ^ super = aSymbol!<br>
<br>
Item was changed:<br>
+ (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable.<br>
+ HashedCollection rehashAll.'!<br>
- (PackageInfo named: 'Collections') postscript: 'Character initializeClassificationTable'!<br>
<br>
<br>
</blockquote></div>
<br>
</blockquote></div></div>