<div><div dir="auto">“Lexicographical comparison” is a pretty standard term, and easy to Google. We didn’t make it up for Swift :)</div><div dir="auto"><br></div><div dir="auto">Since Swift names this protocol Sequence, something named “Sequence.sequenceEqual” cannot distinguish this method from ==.</div><div dir="auto"><br></div><br><div class="gmail_quote"><div>On Fri, Oct 13, 2017 at 01:28 Adam Kemp &lt;<a href="mailto:adam.kemp@apple.com">adam.kemp@apple.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><span style="background-color:rgba(255,255,255,0)">I agree that the proposed name is a poor choice. </span>If we just focus on the naming part, there is precedent in other languages for the name “sequenceEqual”. I think that name makes it a bit clearer that the result is whether the sequences match pair wise rather than whether they have the same elements irrespective of order. I don’t think it entirely solves the problem, but I like it a lot better than the proposed name.<br><br><div id="m_-1509611481453163169AppleMailSignature">--<div>Adam Kemp</div></div></div><div dir="auto"><div><br>On Oct 12, 2017, at 9:57 PM, Kevin Nattinger via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><div>–∞</div><div><br></div>1. I strongly object to the proposed name. It doesn&#39;t make it more clear to me what the method does, and is misleading at best. Among other issues, &quot;lexicographical&quot; is defined as alphabet order, and (1) this method applies to objects that are not Strings, and (2) this method&#39;s behavior isn&#39;t any more well-defined for Strings, so that name is even more of a lie than the original.<div><br><div>2. This is really just a symptom of a bigger problem. The fact that two Sets can compare equal and yet return different results for that method (among too many others) is logically inconsistent and points to a much deeper issue with Set and Sequence. It is probably about 3 releases too late to get this straightened out properly, but I&#39;ll outline the real issue in case someone has an idea for fixing it.</div><div><br></div><div><b>The root of the problem is that Set conforms to Sequence, but Sequence doesn&#39;t require a well-defined order.</b> Since Set doesn&#39;t have a well-defined order, a significant portion of its interface is unspecified. The methods are implemented because they have to be, but they doesn&#39;t have well-defined or necessarily consistent results.<br><br>A sequence is, by definition, ordered. That is reflected in the fact that over half the methods in the main Sequence definition* make no sense and are not well-defined unless there is a well-defined order to the sequence itself. What does it even mean to `dropFirst()` in a Set? The fact that two objects that compare equal can give different results for a 100% deterministic function is illogical, nonsensical, and dangerous.</div><div><br></div><div>* 7/12 by my count, ignoring `_*` funcs but including the `var`<br><br>The current contents of Sequence can be cleanly divided into two groups; those that return SubSequence imply a specific ordering, and the rest do not.</div><div><br></div><div> I think those should be/should have been two separate protocols:</div><div><br></div><div><div style="margin:0px;line-height:normal;font-family:&#39;Andale Mono&#39;;color:rgb(233,175,205);background-color:rgba(0,0,0,0.901961)"><span style="font-variant-ligatures:no-common-ligatures">public</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures">protocol</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">Iterable</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> {</span></div><div style="margin:0px;line-height:normal;font-family:&#39;Andale Mono&#39;;color:rgb(52,188,38);background-color:rgba(0,0,0,0.901961)"><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">  </span><span style="font-variant-ligatures:no-common-ligatures;color:#cd7923">associatedtype</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> Iterator</span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">:</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures">IteratorProtocol</span></div><div style="margin:0px;line-height:normal;font-family:&#39;Andale Mono&#39;;color:rgb(130,185,255);background-color:rgba(0,0,0,0.901961)"><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">  </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">func</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">map</span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">&lt;</span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">T</span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">&gt;</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">(</span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">...</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">) </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">-&gt;</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">[</span><span style="font-variant-ligatures:no-common-ligatures;color:#34bc26">T</span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">]</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures">// Iterable where .Iterator.Element == T</span></div><div style="margin:0px;line-height:normal;font-family:&#39;Andale Mono&#39;;color:rgb(130,185,255);background-color:rgba(0,0,0,0.901961)"><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">  </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">func</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">filter</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">(</span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">...</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">) </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">-&gt;</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">[</span><span style="font-variant-ligatures:no-common-ligatures;color:#34bc26">Iterator.Element</span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">]</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures">// Iterable where .Iterator.Element == Self.Iterator.Element</span></div><div style="margin:0px;line-height:normal;font-family:&#39;Andale Mono&#39;;color:rgb(52,187,200);background-color:rgba(0,0,0,0.901961)"><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">  </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">func</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures">forEach</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">(</span><span style="font-variant-ligatures:no-common-ligatures">...</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">)</span></div><div style="margin:0px;line-height:normal;font-family:&#39;Andale Mono&#39;;color:rgb(52,187,200);background-color:rgba(0,0,0,0.901961)"><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">  </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">func</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures">makeIterator</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">() </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">-&gt;</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#34bc26">Iterator</span></div><div style="margin:0px;line-height:normal;font-family:&#39;Andale Mono&#39;;color:rgb(52,187,200);background-color:rgba(0,0,0,0.901961)"><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">  </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">var</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures">underestimatedCount</span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">:</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#34bc26">Int</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> { </span><span style="font-variant-ligatures:no-common-ligatures;color:#cd7923">get</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> }</span></div><div style="margin:0px;line-height:normal;font-family:&#39;Andale Mono&#39;;color:rgb(214,214,214);background-color:rgba(0,0,0,0.901961)"><span style="font-variant-ligatures:no-common-ligatures">}</span></div><div style="margin:0px;line-height:normal;font-family:&#39;Andale Mono&#39;;color:rgb(214,214,214);background-color:rgba(0,0,0,0.901961);min-height:14px"><span style="font-variant-ligatures:no-common-ligatures"></span><br></div><div style="margin:0px;line-height:normal;font-family:&#39;Andale Mono&#39;;color:rgb(130,185,255);background-color:rgba(0,0,0,0.901961)"><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">public</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">protocol</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">Sequence</span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">:</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#34bc26">Iterable</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> { </span><span style="font-variant-ligatures:no-common-ligatures">// Maybe OrderedSequence just to make the well-defined-order requirement explicit</span></div><div style="margin:0px;line-height:normal;font-family:&#39;Andale Mono&#39;;color:rgb(214,214,214);background-color:rgba(0,0,0,0.901961)"><span style="font-variant-ligatures:no-common-ligatures">  </span><span style="font-variant-ligatures:no-common-ligatures;color:#cd7923">associatedtype</span><span style="font-variant-ligatures:no-common-ligatures"> SubSequence</span></div><div style="margin:0px;line-height:normal;font-family:&#39;Andale Mono&#39;;color:rgb(130,185,255);background-color:rgba(0,0,0,0.901961)"><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">  </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">func</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">dropFirst</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">(</span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">...</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">)   </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">-&gt;</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#34bc26">SubSequence</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">   </span><span style="font-variant-ligatures:no-common-ligatures">// Sequence where .Iterator.Element == Self.Iterator.Element</span></div><div style="margin:0px;line-height:normal;font-family:&#39;Andale Mono&#39;;color:rgb(214,214,214);background-color:rgba(0,0,0,0.901961)"><span style="font-variant-ligatures:no-common-ligatures">  </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">func</span><span style="font-variant-ligatures:no-common-ligatures"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">dropLast</span><span style="font-variant-ligatures:no-common-ligatures">(</span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">...</span><span style="font-variant-ligatures:no-common-ligatures">)    </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">-&gt;</span><span style="font-variant-ligatures:no-common-ligatures"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#34bc26">SubSequence</span><span style="font-variant-ligatures:no-common-ligatures">   </span><span style="font-variant-ligatures:no-common-ligatures;color:#82b9ff">//    &quot; &quot;</span></div><div style="margin:0px;line-height:normal;font-family:&#39;Andale Mono&#39;;color:rgb(214,214,214);background-color:rgba(0,0,0,0.901961)"><span style="font-variant-ligatures:no-common-ligatures">  </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">func</span><span style="font-variant-ligatures:no-common-ligatures"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">drop</span><span style="font-variant-ligatures:no-common-ligatures">(</span><span style="font-variant-ligatures:no-common-ligatures;color:#cd7923">while</span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">...</span><span style="font-variant-ligatures:no-common-ligatures">)   </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">-&gt;</span><span style="font-variant-ligatures:no-common-ligatures"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#34bc26">SubSequence</span><span style="font-variant-ligatures:no-common-ligatures">   </span><span style="font-variant-ligatures:no-common-ligatures;color:#82b9ff">//    &quot; &quot;</span></div><div style="margin:0px;line-height:normal;font-family:&#39;Andale Mono&#39;;color:rgb(214,214,214);background-color:rgba(0,0,0,0.901961)"><span style="font-variant-ligatures:no-common-ligatures">  </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">func</span><span style="font-variant-ligatures:no-common-ligatures"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">prefix</span><span style="font-variant-ligatures:no-common-ligatures">(</span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">...</span><span style="font-variant-ligatures:no-common-ligatures">)      </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">-&gt;</span><span style="font-variant-ligatures:no-common-ligatures"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#34bc26">SubSequence</span><span style="font-variant-ligatures:no-common-ligatures">   </span><span style="font-variant-ligatures:no-common-ligatures;color:#82b9ff">//    &quot; &quot;</span></div><div style="margin:0px;line-height:normal;font-family:&#39;Andale Mono&#39;;color:rgb(52,188,38);background-color:rgba(0,0,0,0.901961)"><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">  </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">func</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">prefix</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">(</span><span style="font-variant-ligatures:no-common-ligatures;color:#cd7923">while</span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">...</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">) </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">-&gt;</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures">SubSequence</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">   </span><span style="font-variant-ligatures:no-common-ligatures;color:#82b9ff">//    &quot; &quot;</span></div><div style="margin:0px;line-height:normal;font-family:&#39;Andale Mono&#39;;color:rgb(214,214,214);background-color:rgba(0,0,0,0.901961)"><span style="font-variant-ligatures:no-common-ligatures">  </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">func</span><span style="font-variant-ligatures:no-common-ligatures"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">suffix</span><span style="font-variant-ligatures:no-common-ligatures">(</span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">...</span><span style="font-variant-ligatures:no-common-ligatures">)      </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">-&gt;</span><span style="font-variant-ligatures:no-common-ligatures"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#34bc26">SubSequence</span><span style="font-variant-ligatures:no-common-ligatures">   </span><span style="font-variant-ligatures:no-common-ligatures;color:#82b9ff">//    &quot; &quot;</span></div><div style="margin:0px;line-height:normal;font-family:&#39;Andale Mono&#39;;color:rgb(130,185,255);background-color:rgba(0,0,0,0.901961)"><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">  </span><span style="font-variant-ligatures:no-common-ligatures;color:#e9afcd">func</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6"> </span><span style="font-variant-ligatures:no-common-ligatures;color:#34bbc8">split</span><span style="font-variant-ligatures:no-common-ligatures;color:#d6d6d6">(</span><span style="color:rgb(52,187,200)">...</span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(205,121,35)">where</span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(52,187,200)">...</span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(214,214,214)">)  </span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(233,175,205)">-&gt;</span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(214,214,214)"> </span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(233,175,205)">[</span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(52,188,38)">SubSequence</span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(233,175,205)">]</span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(214,214,214)"> </span><span style="font-variant-ligatures:no-common-ligatures">// Iterable where .Iterator.Element == (Sequence where .Iterator.Element == Self.Iterator.Element)</span></div><div style="margin:0px;line-height:normal;font-family:&#39;Andale Mono&#39;;color:rgb(214,214,214);background-color:rgba(0,0,0,0.901961)"><span style="font-variant-ligatures:no-common-ligatures">}</span></div><div><span style="font-variant-ligatures:no-common-ligatures"><br></span></div><div><span style="font-variant-ligatures:no-common-ligatures">(The comments, of course, would be more sensible types once the ideas can actually be expressed in Swift)<br><br>Then unordered collections (Set and Dictionary) would just conform to Iterable and not Sequence, so ALL the methods on those classes would make logical sense and have well-defined behavior; no change would be needed for ordered collections.<br><br>Now, the practical matter. If this were Swift 1-&gt;2 or 2-&gt;3, I doubt there would be a significant issue with actually making this change. Unfortunately, we&#39;re well beyond that and making a change this deep is an enormous deal. So I see two ways forward.<br><br>1. We could go ahead and make this separation. Although it&#39;s a potentially large breaking change, I would argue that because the methods are ill-defined anyway, the breakage is justified and a net benefit.<br><br>2. We could try and think of a way to make the distinction between ordered and unordered &quot;sequences&quot; in a less-breaking manner. Unfortunately, I don&#39;t have a good suggestion for this, but if anyone has ideas, I&#39;m all ears. Or eyes, as the case may be.<br><br></span></div><br></div><div><div><blockquote type="cite"><div>On Oct 12, 2017, at 4:24 PM, Xiaodi Wu via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br class="m_-1509611481453163169Apple-interchange-newline"><div><div><h1>Rename <code>Sequence.elementsEqual</code></h1>
<ul><li>Proposal: <a href="https://gist.github.com/xwu/NNNN-rename-elements-equal.md" target="_blank">SE-NNNN</a></li><li>Authors: <a href="https://github.com/xwu" target="_blank">Xiaodi Wu</a></li><li>Review Manager: TBD</li><li>Status: <strong>Awaiting review</strong></li></ul><h2><a href="https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#introduction" class="m_-1509611481453163169gmail-anchor" id="m_-1509611481453163169gmail-user-content-introduction" target="_blank"></a>Introduction</h2><p>The current behavior of <code>Sequence.elementsEqual</code> is 
potentially confusing to users given its name. Having surveyed the 
alternative solutions to this problem, it is proposed that the method be
 renamed to <code>Sequence.lexicographicallyEquals</code>.</p><div>[...]</div></div></div></blockquote></div></div></div></div></blockquote></div><div dir="auto"><blockquote type="cite"><div><span>_______________________________________________</span></div></blockquote></div><div dir="auto"><blockquote type="cite"><div><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></div></blockquote></div></div>