# \[Draft\] Rename Sequence.elementsEqual

**URL:** <https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821>\
**Category:** Discussion\
**Created:** [October 12, 2017, 11:23pm UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821 "2017-10-12T23:23:53Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [October 12, 2017, 11:23pm UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/1 "2017-10-12T23:23:53Z")

</div>

Rename Sequence.elementsEqual

&nbsp;&nbsp;&nbsp;- Proposal: SE-NNNN  
&nbsp;&nbsp;&nbsp;\<[https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt](https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt);  
&nbsp;&nbsp;&nbsp;- Authors: Xiaodi Wu \<[https://github.com/xwu&gt](https://github.com/xwu&gt);  
&nbsp;&nbsp;&nbsp;- Review Manager: TBD  
&nbsp;&nbsp;&nbsp;- Status: \*Awaiting review\*

\<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#introduction&gt);  
Introduction

The current behavior of Sequence.elementsEqual 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  
Sequence.lexicographicallyEquals.  
\<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#motivation&gt);  
Motivation

As outlined by Ole Begemann  
\<[https://twitter.com/olebegemann/status/916291785185529857&gt;](https://twitter.com/olebegemann/status/916291785185529857&gt;), use of  
Sequence.elementsEqual(\_:) can lead to surprising results if the sequences  
compared are unordered:

var set1: Set\<Int\> = Set(1...5)var set2: Set\<Int\> = Set((1...5).reversed())

set1 == set2 // trueset1.elementsEqual(set2) // false

This result does reflect the \*intended and documented\* behavior of the  
elementsEqual(\_:) method, which performs a \*lexicographical\* elementwise  
comparison. That is, the method first compares set1.first to set2.first,  
then (if the two elements compare equal) compares the next element stored  
internally in set1 to the next element stored internally in set2, and so on.

In almost all circumstances where a set is compared to another set, or a  
dictionary is compared to another dictionary, users should use == instead  
of elementsEqual(\_:).  
\<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#proposed-solution&gt;Proposed)  
solution

The proposed solution is the result of an iterative process of reasoning,  
presented here:

The first and most obvious solution is to remove the elementsEqual(\_:)  
method altogether in favor of ==. This prevents its misuse. However,  
because elementsEqual(\_:) is a generic method on Sequence, we can use it to  
compare an instance of UnsafeBufferPointer\<Int\> to an instance of [Int].  
This is a useful and non-redundant feature which would be eliminated if the  
method is removed altogether.

A second solution \<[https://github.com/apple/swift/pull/12318&gt](https://github.com/apple/swift/pull/12318&gt); is to create  
overloads that forbid the use of the elementsEqual(\_:) method specifically  
in non-generic code. This would prevent misuse in non-generic code;  
however, it would also forbid legitimate mixed-type comparisons in  
non-generic code while failing to prevent misuse in generic code. The  
solution also creates a difference in the behavior of generic and  
non-generic code calling the same method, which is potentially confusing,  
without solving the problem completely.

A third solution is to dramatically overhaul the protocol hierarchy for  
Swift sequences and collections so that unordered collections no longer  
have members such as first and elementsEqual(\_:). However, this would be a  
colossal and source-breaking undertaking, and it is unlikely to be  
satisfactory in addressing all the axes of differences among sequence and  
collection types:

&nbsp;&nbsp;&nbsp;- Finite versus infinite  
&nbsp;&nbsp;&nbsp;- Single-pass versus multi-pass  
&nbsp;&nbsp;&nbsp;- Ordered versus unordered  
&nbsp;&nbsp;&nbsp;- Lazy versus eager  
&nbsp;&nbsp;&nbsp;- Forward/bidirectional/random-access

A fourth solution is proposed here. It is predicated on the following  
observation:

\*Another method similar to elementsEqual(\_:) already exists on Sequence  
named lexicographicallyPrecedes(\_:). Like first, elementsEqual(\_:),  
drop(while:), and others, it relies on the internal order of elements in a  
manner that is not completely suitable for an unordered collection.  
However, like first and unlike elementsEqual(\_:), this fact is called out  
in the name of the method; unsurprisingly, like first and unlike  
elementsEqual(\_:), there is no evidence that lexicographicallyPrecedes(\_:)  
has been a pitfall for users.\*

This observation suggests that a major reason for confusion over  
elementsEqual(\_:) stems from its name. So, \*it is proposed that  
elementsEqual(\_:) should be renamed to lexicographicallyEquals(\_:)\*. The  
function will remain somewhat of a poor fit for unordered collections, but  
no more so than many other methods that cannot trivially be removed from  
the API of unordered collections (as discussed above). The key is that,  
with such a renaming, the behavior of this method will no longer be  
confusing.  
\<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#detailed-design&gt;Detailed)  
design

extension Sequence where Element : Equatable {  
&nbsp;&nbsp;@available(\*, deprecated, message: "Use '==' if possible to compare  
two sequences of the same type, or use 'lexicographicallyEquals' to  
compare two ordered sequences.")  
&nbsp;&nbsp;public func elementsEqual\<Other : Sequence\>(  
&nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
&nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
&nbsp;&nbsp;&nbsp;&nbsp;return lexicographicallyEquals(other)  
&nbsp;&nbsp;}

&nbsp;&nbsp;public func lexicographicallyEquals\<Other : Sequence\>(  
&nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
&nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
&nbsp;&nbsp;&nbsp;&nbsp;// The body of this method is unchanged. var iter1 = self.makeIterator()  
&nbsp;&nbsp;&nbsp;&nbsp;var iter2 = other.makeIterator()  
&nbsp;&nbsp;&nbsp;&nbsp;while true {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch (iter1.next(), iter2.next()) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case let (e1?, e2?):  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if e1 != e2 { return false }  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (\_?, nil), (nil, \_?):  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (nil, nil):  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;}  
}

A parallel change will be made with respect to elementsEqual(\_:by:); that  
is, it will be deprecated in favor of lexicographicallyEquals(\_:by:).  
\<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#source-compatibility&gt;Source)  
compatibility

Existing code that uses elementsEqual will gain a deprecation warning.  
\<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#effect-on-abi-stability&gt;Effect)  
on ABI stability

None.  
\<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#effect-on-api-resilience&gt;Effect)  
on API resilience

This proposal adds new methods to the public API of Sequence and conforming  
types.  
\<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#alternatives-considered&gt;Alternatives)  
considered

It is to be noted that lexicographicallyPrecedes(\_:by:) and  
elementsEqual(\_:by:) are essentially the same method, since both perform a  
lexicographical comparison using a custom predicate. However, there is not  
a good unifying name. (lexicographicallyCompares(to:by:) reads poorly.)  
Moreover, the predicate supplied is intended to have very different  
semantics, and maintaining two distinct methods may be a superior fit with  
the typical user's mental model of the intended behavior and may also be  
clearer to readers of the code. Therefore, this proposal does not seek to  
unify the two methods; instead, elementsEqual(\_:by:) will be renamed  
lexicographicallyEquals(\_:by:) as detailed above.

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [October 12, 2017, 11:37pm UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/2 "2017-10-12T23:37:51Z")

</div>

I’ve always hated the use of the word “lexicographically” in that method 1)  
because lexicographically is hard to spell, and 2) because it’s weird to  
say that an unordered collection has a lexicographical order. But this  
change is probably for the best.

> **···**
>
> On Thu, Oct 12, 2017 at 6:24 PM, Xiaodi Wu via swift-evolution \< swift-evolution@swift.org\> wrote:
> 
> > Rename Sequence.elementsEqual
> > 
> > &nbsp;&nbsp;&nbsp;- Proposal: SE-NNNN  
> > &nbsp;&nbsp;&nbsp;\<[https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt](https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt);  
> > &nbsp;&nbsp;&nbsp;- Authors: Xiaodi Wu \<[https://github.com/xwu&gt](https://github.com/xwu&gt);  
> > &nbsp;&nbsp;&nbsp;- Review Manager: TBD  
> > &nbsp;&nbsp;&nbsp;- Status: \*Awaiting review\*
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#introduction&gt);  
> > Introduction
> > 
> > The current behavior of Sequence.elementsEqual 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 Sequence.  
> > lexicographicallyEquals.  
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#motivation&gt);  
> > Motivation
> > 
> > As outlined by Ole Begemann  
> > \<[https://twitter.com/olebegemann/status/916291785185529857&gt;](https://twitter.com/olebegemann/status/916291785185529857&gt;), use of  
> > Sequence.elementsEqual(\_:) can lead to surprising results if the  
> > sequences compared are unordered:
> > 
> > var set1: Set\<Int\> = Set(1...5)var set2: Set\<Int\> = Set((1...5).reversed())
> > 
> > set1 == set2 // trueset1.elementsEqual(set2) // false
> > 
> > This result does reflect the \*intended and documented\* behavior of the  
> > elementsEqual(\_:) method, which performs a \*lexicographical\* elementwise  
> > comparison. That is, the method first compares set1.first to set2.first,  
> > then (if the two elements compare equal) compares the next element stored  
> > internally in set1 to the next element stored internally in set2, and so  
> > on.
> > 
> > In almost all circumstances where a set is compared to another set, or a  
> > dictionary is compared to another dictionary, users should use == instead  
> > of elementsEqual(\_:).
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#proposed-solution&gt;Proposed)  
> > solution
> > 
> > The proposed solution is the result of an iterative process of reasoning,  
> > presented here:
> > 
> > The first and most obvious solution is to remove the elementsEqual(\_:)  
> > method altogether in favor of ==. This prevents its misuse. However,  
> > because elementsEqual(\_:) is a generic method on Sequence, we can use it  
> > to compare an instance of UnsafeBufferPointer\<Int\> to an instance of [Int].  
> > This is a useful and non-redundant feature which would be eliminated if the  
> > method is removed altogether.
> > 
> > A second solution \<[https://github.com/apple/swift/pull/12318&gt](https://github.com/apple/swift/pull/12318&gt); is to  
> > create overloads that forbid the use of the elementsEqual(\_:) method  
> > specifically in non-generic code. This would prevent misuse in non-generic  
> > code; however, it would also forbid legitimate mixed-type comparisons in  
> > non-generic code while failing to prevent misuse in generic code. The  
> > solution also creates a difference in the behavior of generic and  
> > non-generic code calling the same method, which is potentially confusing,  
> > without solving the problem completely.
> > 
> > A third solution is to dramatically overhaul the protocol hierarchy for  
> > Swift sequences and collections so that unordered collections no longer  
> > have members such as first and elementsEqual(\_:). However, this would be  
> > a colossal and source-breaking undertaking, and it is unlikely to be  
> > satisfactory in addressing all the axes of differences among sequence and  
> > collection types:
> > 
> > &nbsp;&nbsp;&nbsp;- Finite versus infinite  
> > &nbsp;&nbsp;&nbsp;- Single-pass versus multi-pass  
> > &nbsp;&nbsp;&nbsp;- Ordered versus unordered  
> > &nbsp;&nbsp;&nbsp;- Lazy versus eager  
> > &nbsp;&nbsp;&nbsp;- Forward/bidirectional/random-access
> > 
> > A fourth solution is proposed here. It is predicated on the following  
> > observation:
> > 
> > \*Another method similar to elementsEqual(\_:) already exists on Sequence  
> > named lexicographicallyPrecedes(\_:). Like first, elementsEqual(\_:),  
> > drop(while:), and others, it relies on the internal order of elements in a  
> > manner that is not completely suitable for an unordered collection.  
> > However, like first and unlike elementsEqual(\_:), this fact is called out  
> > in the name of the method; unsurprisingly, like first and unlike  
> > elementsEqual(\_:), there is no evidence that lexicographicallyPrecedes(\_:)  
> > has been a pitfall for users.\*
> > 
> > This observation suggests that a major reason for confusion over  
> > elementsEqual(\_:) stems from its name. So, \*it is proposed that  
> > elementsEqual(\_:) should be renamed to lexicographicallyEquals(\_:)\*. The  
> > function will remain somewhat of a poor fit for unordered collections, but  
> > no more so than many other methods that cannot trivially be removed from  
> > the API of unordered collections (as discussed above). The key is that,  
> > with such a renaming, the behavior of this method will no longer be  
> > confusing.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#detailed-design&gt;Detailed)  
> > design
> > 
> > extension Sequence where Element : Equatable {  
> > &nbsp;&nbsp;@available(\*, deprecated, message: "Use '==' if possible to compare two sequences of the same type, or use 'lexicographicallyEquals' to compare two ordered sequences.")  
> > &nbsp;&nbsp;public func elementsEqual\<Other : Sequence\>(  
> > &nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
> > &nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
> > &nbsp;&nbsp;&nbsp;&nbsp;return lexicographicallyEquals(other)  
> > &nbsp;&nbsp;}
> > 
> > &nbsp;&nbsp;public func lexicographicallyEquals\<Other : Sequence\>(  
> > &nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
> > &nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
> > &nbsp;&nbsp;&nbsp;&nbsp;// The body of this method is unchanged. var iter1 = self.makeIterator()  
> > &nbsp;&nbsp;&nbsp;&nbsp;var iter2 = other.makeIterator()  
> > &nbsp;&nbsp;&nbsp;&nbsp;while true {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch (iter1.next(), iter2.next()) {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case let (e1?, e2?):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if e1 != e2 { return false }  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (\_?, nil), (nil, \_?):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (nil, nil):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;}  
> > }
> > 
> > A parallel change will be made with respect to elementsEqual(\_:by:); that  
> > is, it will be deprecated in favor of lexicographicallyEquals(\_:by:).
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#source-compatibility&gt;Source)  
> > compatibility
> > 
> > Existing code that uses elementsEqual will gain a deprecation warning.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#effect-on-abi-stability&gt;Effect)  
> > on ABI stability
> > 
> > None.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#effect-on-api-resilience&gt;Effect)  
> > on API resilience
> > 
> > This proposal adds new methods to the public API of Sequence and  
> > conforming types.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#alternatives-considered&gt;Alternatives)  
> > considered
> > 
> > It is to be noted that lexicographicallyPrecedes(\_:by:) and  
> > elementsEqual(\_:by:) are essentially the same method, since both perform  
> > a lexicographical comparison using a custom predicate. However, there is  
> > not a good unifying name. (lexicographicallyCompares(to:by:) reads  
> > poorly.) Moreover, the predicate supplied is intended to have very  
> > different semantics, and maintaining two distinct methods may be a superior  
> > fit with the typical user's mental model of the intended behavior and may  
> > also be clearer to readers of the code. Therefore, this proposal does not  
> > seek to unify the two methods; instead, elementsEqual(\_:by:) will be  
> > renamed lexicographicallyEquals(\_:by:) as detailed above.
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![knatt](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/knatt/32/22335_2.png) [@knatt](https://forums.swift.org/u/knatt)\
**Post date:** [October 13, 2017, 4:57am UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/3 "2017-10-13T04:57:19Z")

</div>

–∞

1. I strongly object to the proposed name. It doesn't make it more clear to me what the method does, and is misleading at best. Among other issues, "lexicographical" is defined as alphabet order, and (1) this method applies to objects that are not Strings, and (2) this method's behavior isn't any more well-defined for Strings, so that name is even more of a lie than the original.

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'll outline the real issue in case someone has an idea for fixing it.

The root of the problem is that Set conforms to Sequence, but Sequence doesn't require a well-defined order. Since Set doesn'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't have well-defined or necessarily consistent results.

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.

\* 7/12 by my count, ignoring `_*` funcs but including the `var`

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.

I think those should be/should have been two separate protocols:

public protocol Iterable {  
&nbsp;&nbsp;associatedtype Iterator: IteratorProtocol  
&nbsp;&nbsp;func map\<T\>(...) -\> [T] // Iterable where .Iterator.Element == T  
&nbsp;&nbsp;func filter(...) -\> [Iterator.Element] // Iterable where .Iterator.Element == Self.Iterator.Element  
&nbsp;&nbsp;func forEach(...)  
&nbsp;&nbsp;func makeIterator() -\> Iterator  
&nbsp;&nbsp;var underestimatedCount: Int { get }  
}

public protocol Sequence: Iterable { // Maybe OrderedSequence just to make the well-defined-order requirement explicit  
&nbsp;&nbsp;associatedtype SubSequence  
&nbsp;&nbsp;func dropFirst(...) -\> SubSequence // Sequence where .Iterator.Element == Self.Iterator.Element  
&nbsp;&nbsp;func dropLast(...) -\> SubSequence // " "  
&nbsp;&nbsp;func drop(while...) -\> SubSequence // " "  
&nbsp;&nbsp;func prefix(...) -\> SubSequence // " "  
&nbsp;&nbsp;func prefix(while...) -\> SubSequence // " "  
&nbsp;&nbsp;func suffix(...) -\> SubSequence // " "  
&nbsp;&nbsp;func split(...where...) -\> [SubSequence] // Iterable where .Iterator.Element == (Sequence where .Iterator.Element == Self.Iterator.Element)  
}

(The comments, of course, would be more sensible types once the ideas can actually be expressed in Swift)

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.

Now, the practical matter. If this were Swift 1-\>2 or 2-\>3, I doubt there would be a significant issue with actually making this change. Unfortunately, we're well beyond that and making a change this deep is an enormous deal. So I see two ways forward.

1. We could go ahead and make this separation. Although it'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.

2. We could try and think of a way to make the distinction between ordered and unordered "sequences" in a less-breaking manner. Unfortunately, I don't have a good suggestion for this, but if anyone has ideas, I'm all ears. Or eyes, as the case may be.

> **···**
>
> > On Oct 12, 2017, at 4:24 PM, Xiaodi Wu via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > Rename Sequence.elementsEqual
> > 
> > Proposal: SE-NNNN \<[https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt](https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt);  
> > Authors: Xiaodi Wu \<[https://github.com/xwu&gt](https://github.com/xwu&gt);  
> > Review Manager: TBD  
> > Status: Awaiting review  
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#introduction&gt;Introduction)
> > 
> > The current behavior of Sequence.elementsEqual 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 Sequence.lexicographicallyEquals.
> > 
> > [...]

---

<div class="post-metadata">

**Author:** ![jarod](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jarod/32/364_2.png) [@jarod](https://forums.swift.org/u/jarod)\
**Post date:** [October 13, 2017, 6:07pm UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/4 "2017-10-13T18:07:01Z")

</div>

The name that feels natural to me would be `sequentiallyEquals`. I don't dispute that the term "lexicographical" is used correctly here, although at least for me personally, it's not a word that I encounter frequently enough to understand what this method would do without reading the documentation. Like Kevin, if I were to guess what the method did without checking, I would probably think that it compared lexicographically-sorted versions of the collections.

But the consistency with `lexicographicallyPrecedes` is a pretty strong argument, although `sequentiallyPrecedes` would also feel more natural to me there, and my suspicion about the mentioned lack of evidence that the method has been a pitfall for users is that it's not actually used often enough out in the wild to have heard much about it. That's just a guess though. This proposal is the first time I've learned of its existence.

In any case, my ideal version of this proposal would use `sequentiallyEquals` and also rename `lexicographicallyPrecedes` to `sequentiallyPrecedes`, but I still like the proposal overall as-is. Thanks for bringing it forward!

Jarod

> **···**
>
> On Oct 12, 2017, 16:24 -0700, Xiaodi Wu via swift-evolution \<swift-evolution@swift.org\>, wrote:
> 
> > Rename Sequence.elementsEqual
> > 
> > • Proposal: SE-NNNN  
> > • Authors: Xiaodi Wu  
> > • Review Manager: TBD  
> > • Status: Awaiting review
> > 
> > Introduction  
> > The current behavior of Sequence.elementsEqual 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 Sequence.lexicographicallyEquals.  
> > Motivation  
> > As outlined by Ole Begemann, use of Sequence.elementsEqual(\_:) can lead to surprising results if the sequences compared are unordered:  
> > var set1: Set\<Int\> = Set(1...5)  
> > var set2: Set\<Int\> = Set((1...5).reversed())
> > 
> > set1 == set2 // true  
> > set1.elementsEqual(set2) // false  
> > This result does reflect the intended and documented behavior of the elementsEqual(\_:) method, which performs a lexicographical elementwise comparison. That is, the method first compares set1.first to set2.first, then (if the two elements compare equal) compares the next element stored internally in set1 to the next element stored internally in set2, and so on.  
> > In almost all circumstances where a set is compared to another set, or a dictionary is compared to another dictionary, users should use == instead of elementsEqual(\_:).  
> > Proposed solution  
> > The proposed solution is the result of an iterative process of reasoning, presented here:  
> > The first and most obvious solution is to remove the elementsEqual(\_:) method altogether in favor of ==. This prevents its misuse. However, because elementsEqual(\_:) is a generic method on Sequence, we can use it to compare an instance of UnsafeBufferPointer\<Int\> to an instance of [Int]. This is a useful and non-redundant feature which would be eliminated if the method is removed altogether.  
> > A second solution is to create overloads that forbid the use of the elementsEqual(\_:) method specifically in non-generic code. This would prevent misuse in non-generic code; however, it would also forbid legitimate mixed-type comparisons in non-generic code while failing to prevent misuse in generic code. The solution also creates a difference in the behavior of generic and non-generic code calling the same method, which is potentially confusing, without solving the problem completely.  
> > A third solution is to dramatically overhaul the protocol hierarchy for Swift sequences and collections so that unordered collections no longer have members such as first and elementsEqual(\_:). However, this would be a colossal and source-breaking undertaking, and it is unlikely to be satisfactory in addressing all the axes of differences among sequence and collection types:
> > 
> > • Finite versus infinite  
> > • Single-pass versus multi-pass  
> > • Ordered versus unordered  
> > • Lazy versus eager  
> > • Forward/bidirectional/random-access
> > 
> > A fourth solution is proposed here. It is predicated on the following observation:  
> > Another method similar to elementsEqual(\_:) already exists on Sequence named lexicographicallyPrecedes(\_:). Like first, elementsEqual(\_:), drop(while:), and others, it relies on the internal order of elements in a manner that is not completely suitable for an unordered collection. However, like first and unlike elementsEqual(\_:), this fact is called out in the name of the method; unsurprisingly, like first and unlike elementsEqual(\_:), there is no evidence that lexicographicallyPrecedes(\_:) has been a pitfall for users.  
> > This observation suggests that a major reason for confusion over elementsEqual(\_:) stems from its name. So, it is proposed that elementsEqual(\_:) should be renamed to lexicographicallyEquals(\_:). The function will remain somewhat of a poor fit for unordered collections, but no more so than many other methods that cannot trivially be removed from the API of unordered collections (as discussed above). The key is that, with such a renaming, the behavior of this method will no longer be confusing.  
> > Detailed design  
> > extension Sequence where Element : Equatable {  
> > @available(\*, deprecated, message: "Use '==' if possible to compare two sequences of the same type, or use 'lexicographicallyEquals' to compare two ordered sequences.")  
> > public func elementsEqual\<Other : Sequence\>(  
> > &nbsp;&nbsp;&nbsp;\_ other: Other  
> > ) -\> Bool where Other.Element == Element {  
> > &nbsp;&nbsp;&nbsp;return lexicographicallyEquals(other)  
> > }
> > 
> > public func lexicographicallyEquals\<Other : Sequence\>(  
> > &nbsp;&nbsp;&nbsp;\_ other: Other  
> > ) -\> Bool where Other.Element == Element {  
> > &nbsp;&nbsp;&nbsp;// The body of this method is unchanged.  
> > &nbsp;&nbsp;&nbsp;var iter1 = self.makeIterator()  
> > &nbsp;&nbsp;&nbsp;var iter2 = other.makeIterator()  
> > &nbsp;&nbsp;&nbsp;while true {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch (iter1.next(), iter2.next()) {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case let (e1?, e2?):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if e1 != e2 { return false }  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (\_?, nil), (nil, \_?):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (nil, nil):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;}  
> > }  
> > }  
> > A parallel change will be made with respect to elementsEqual(\_:by:); that is, it will be deprecated in favor of lexicographicallyEquals(\_:by:).  
> > Source compatibility  
> > Existing code that uses elementsEqual will gain a deprecation warning.  
> > Effect on ABI stability  
> > None.  
> > Effect on API resilience  
> > This proposal adds new methods to the public API of Sequence and conforming types.  
> > Alternatives considered  
> > It is to be noted that lexicographicallyPrecedes(\_:by:) and elementsEqual(\_:by:) are essentially the same method, since both perform a lexicographical comparison using a custom predicate. However, there is not a good unifying name. (lexicographicallyCompares(to:by:) reads poorly.) Moreover, the predicate supplied is intended to have very different semantics, and maintaining two distinct methods may be a superior fit with the typical user's mental model of the intended behavior and may also be clearer to readers of the code. Therefore, this proposal does not seek to unify the two methods; instead, elementsEqual(\_:by:) will be renamed lexicographicallyEquals(\_:by:) as detailed above.  
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![cpwhidden](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/cpwhidden/32/318_2.png) [@cpwhidden](https://forums.swift.org/u/cpwhidden)\
**Post date:** [October 13, 2017, 9:52pm UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/5 "2017-10-13T21:52:19Z")

</div>

Using the term “lexicographically” implies to me that the Element type must conform to Comparable, as would be required for a total order. The Sequence method you mention, lexicographicallyPrecedes(\_:), does have this constraint, whereas the method in question for elementsEqual(\_:) / lexicographicallyEquals(\_:) only has the constraint that the Element is Equatable. As an example, an array of simple enums has no default lexicographical ordering but is still able to use this method because enums (without associated values) are Equatable by default:

enum Foo {  
&nbsp;&nbsp;&nbsp;&nbsp;case bar  
&nbsp;&nbsp;&nbsp;&nbsp;case baz  
}

let f1 = [Foo.bar, Foo.baz]  
let f2 = [Foo.baz, Foo.bar]

f1.elementsEqual(f2) //false  
f1.elementsEqual(f2.reversed()) //true

I also share Jonathan’s concerns that some programmers may misinterpret [lexicographically][Equals] to mean [sorted in lexicographical order][compare sequence equality], which is not what the method in question does.

Xiaodi, I think you are right that Sequence.sequentiallyEquals is to close to "==" to use, but I think we have to find something better here.

I’ll recommend that we use the name Sequence.iterativelyEquals(\_:) since this describes the body of the method concisely. A rough abbreviation of this algorithm is:

1. Iterate over elements in two sequences  
&nbsp;&nbsp;a. Compare elements for equality

“iterativelyEquals" concisely describes this.

> **···**
>
> > On Oct 12, 2017, at 6:24 PM, Xiaodi Wu via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > Rename Sequence.elementsEqual
> > 
> > Proposal: SE-NNNN \<[https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt](https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt);  
> > Authors: Xiaodi Wu \<[https://github.com/xwu&gt](https://github.com/xwu&gt);  
> > Review Manager: TBD  
> > Status: Awaiting review  
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#introduction&gt;Introduction)
> > 
> > The current behavior of Sequence.elementsEqual 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 Sequence.lexicographicallyEquals.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#motivation&gt;Motivation)
> > 
> > As outlined by Ole Begemann \<[https://twitter.com/olebegemann/status/916291785185529857&gt;](https://twitter.com/olebegemann/status/916291785185529857&gt;), use of Sequence.elementsEqual(\_:) can lead to surprising results if the sequences compared are unordered:
> > 
> > var set1: Set\<Int\> = Set(1...5)  
> > var set2: Set\<Int\> = Set((1...5).reversed())
> > 
> > set1 == set2 // true  
> > set1.elementsEqual(set2) // false  
> > This result does reflect the intended and documented behavior of the elementsEqual(\_:) method, which performs a lexicographical elementwise comparison. That is, the method first compares set1.first to set2.first, then (if the two elements compare equal) compares the next element stored internally in set1 to the next element stored internally in set2, and so on.
> > 
> > In almost all circumstances where a set is compared to another set, or a dictionary is compared to another dictionary, users should use == instead of elementsEqual(\_:).
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#proposed-solution&gt;Proposed) solution
> > 
> > The proposed solution is the result of an iterative process of reasoning, presented here:
> > 
> > The first and most obvious solution is to remove the elementsEqual(\_:) method altogether in favor of ==. This prevents its misuse. However, because elementsEqual(\_:) is a generic method on Sequence, we can use it to compare an instance of UnsafeBufferPointer\<Int\> to an instance of [Int]. This is a useful and non-redundant feature which would be eliminated if the method is removed altogether.
> > 
> > A second solution \<[https://github.com/apple/swift/pull/12318&gt](https://github.com/apple/swift/pull/12318&gt); is to create overloads that forbid the use of the elementsEqual(\_:) method specifically in non-generic code. This would prevent misuse in non-generic code; however, it would also forbid legitimate mixed-type comparisons in non-generic code while failing to prevent misuse in generic code. The solution also creates a difference in the behavior of generic and non-generic code calling the same method, which is potentially confusing, without solving the problem completely.
> > 
> > A third solution is to dramatically overhaul the protocol hierarchy for Swift sequences and collections so that unordered collections no longer have members such as first and elementsEqual(\_:). However, this would be a colossal and source-breaking undertaking, and it is unlikely to be satisfactory in addressing all the axes of differences among sequence and collection types:
> > 
> > Finite versus infinite  
> > Single-pass versus multi-pass  
> > Ordered versus unordered  
> > Lazy versus eager  
> > Forward/bidirectional/random-access  
> > A fourth solution is proposed here. It is predicated on the following observation:
> > 
> > Another method similar to elementsEqual(\_:) already exists on Sequence named lexicographicallyPrecedes(\_:). Like first, elementsEqual(\_:), drop(while:), and others, it relies on the internal order of elements in a manner that is not completely suitable for an unordered collection. However, like first and unlike elementsEqual(\_:), this fact is called out in the name of the method; unsurprisingly, like first and unlike elementsEqual(\_:), there is no evidence that lexicographicallyPrecedes(\_:) has been a pitfall for users.
> > 
> > This observation suggests that a major reason for confusion over elementsEqual(\_:) stems from its name. So, it is proposed that elementsEqual(\_:) should be renamed to lexicographicallyEquals(\_:). The function will remain somewhat of a poor fit for unordered collections, but no more so than many other methods that cannot trivially be removed from the API of unordered collections (as discussed above). The key is that, with such a renaming, the behavior of this method will no longer be confusing.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#detailed-design&gt;Detailed) design
> > 
> > extension Sequence where Element : Equatable {  
> > &nbsp;&nbsp;@available(\*, deprecated, message: "Use '==' if possible to compare two sequences of the same type, or use 'lexicographicallyEquals' to compare two ordered sequences.")  
> > &nbsp;&nbsp;public func elementsEqual\<Other : Sequence\>(  
> > &nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
> > &nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
> > &nbsp;&nbsp;&nbsp;&nbsp;return lexicographicallyEquals(other)  
> > &nbsp;&nbsp;}  
> > &nbsp;&nbsp;  
> > &nbsp;&nbsp;public func lexicographicallyEquals\<Other : Sequence\>(  
> > &nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
> > &nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
> > &nbsp;&nbsp;&nbsp;&nbsp;// The body of this method is unchanged.  
> > &nbsp;&nbsp;&nbsp;&nbsp;var iter1 = self.makeIterator()  
> > &nbsp;&nbsp;&nbsp;&nbsp;var iter2 = other.makeIterator()  
> > &nbsp;&nbsp;&nbsp;&nbsp;while true {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch (iter1.next(), iter2.next()) {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case let (e1?, e2?):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if e1 != e2 { return false }  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (\_?, nil), (nil, \_?):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (nil, nil):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;}  
> > }  
> > A parallel change will be made with respect to elementsEqual(\_:by:); that is, it will be deprecated in favor of lexicographicallyEquals(\_:by:).
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#source-compatibility&gt;Source) compatibility
> > 
> > Existing code that uses elementsEqual will gain a deprecation warning.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#effect-on-abi-stability&gt;Effect) on ABI stability
> > 
> > None.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#effect-on-api-resilience&gt;Effect) on API resilience
> > 
> > This proposal adds new methods to the public API of Sequence and conforming types.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#alternatives-considered&gt;Alternatives) considered
> > 
> > It is to be noted that lexicographicallyPrecedes(\_:by:) and elementsEqual(\_:by:) are essentially the same method, since both perform a lexicographical comparison using a custom predicate. However, there is not a good unifying name. (lexicographicallyCompares(to:by:) reads poorly.) Moreover, the predicate supplied is intended to have very different semantics, and maintaining two distinct methods may be a superior fit with the typical user's mental model of the intended behavior and may also be clearer to readers of the code. Therefore, this proposal does not seek to unify the two methods; instead, elementsEqual(\_:by:) will be renamed lexicographicallyEquals(\_:by:) as detailed above.
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![benjamin.g](https://avatars.discourse-cdn.com/v4/letter/b/9fc29f/32.png) [@benjamin.g](https://forums.swift.org/u/benjamin.g)\
**Post date:** [October 14, 2017, 8:03pm UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/6 "2017-10-14T20:03:59Z")

</div>

To answer more precisely this request (which remains valid no matter the  
protocol hierarchy). I propose

"matchesSequence" ( or simply "matches" or "match", whatever is more  
coherent with the naming guidelines).

So  
var a: [Int] = [1,2,3]  
a.matchesSequence([1,2,3]) returns true.

I first thought that the verb "matching" was too heavily associated to  
regular expressions, but i think that it's the correct equivalent for  
something as general as a sequence.

> **···**
>
> On Fri, Oct 13, 2017 at 1:24 AM, Xiaodi Wu via swift-evolution \< swift-evolution@swift.org\> wrote:
> 
> > Rename Sequence.elementsEqual
> > 
> > &nbsp;&nbsp;&nbsp;- Proposal: SE-NNNN  
> > &nbsp;&nbsp;&nbsp;\<[https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt](https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt);  
> > &nbsp;&nbsp;&nbsp;- Authors: Xiaodi Wu \<[https://github.com/xwu&gt](https://github.com/xwu&gt);  
> > &nbsp;&nbsp;&nbsp;- Review Manager: TBD  
> > &nbsp;&nbsp;&nbsp;- Status: \*Awaiting review\*
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#introduction&gt);  
> > Introduction
> > 
> > The current behavior of Sequence.elementsEqual 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 Sequence.  
> > lexicographicallyEquals.  
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#motivation&gt);  
> > Motivation
> > 
> > As outlined by Ole Begemann  
> > \<[https://twitter.com/olebegemann/status/916291785185529857&gt;](https://twitter.com/olebegemann/status/916291785185529857&gt;), use of  
> > Sequence.elementsEqual(\_:) can lead to surprising results if the  
> > sequences compared are unordered:
> > 
> > var set1: Set\<Int\> = Set(1...5)var set2: Set\<Int\> = Set((1...5).reversed())
> > 
> > set1 == set2 // trueset1.elementsEqual(set2) // false
> > 
> > This result does reflect the \*intended and documented\* behavior of the  
> > elementsEqual(\_:) method, which performs a \*lexicographical\* elementwise  
> > comparison. That is, the method first compares set1.first to set2.first,  
> > then (if the two elements compare equal) compares the next element stored  
> > internally in set1 to the next element stored internally in set2, and so  
> > on.
> > 
> > In almost all circumstances where a set is compared to another set, or a  
> > dictionary is compared to another dictionary, users should use == instead  
> > of elementsEqual(\_:).
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#proposed-solution&gt;Proposed)  
> > solution
> > 
> > The proposed solution is the result of an iterative process of reasoning,  
> > presented here:
> > 
> > The first and most obvious solution is to remove the elementsEqual(\_:)  
> > method altogether in favor of ==. This prevents its misuse. However,  
> > because elementsEqual(\_:) is a generic method on Sequence, we can use it  
> > to compare an instance of UnsafeBufferPointer\<Int\> to an instance of [Int].  
> > This is a useful and non-redundant feature which would be eliminated if the  
> > method is removed altogether.
> > 
> > A second solution \<[https://github.com/apple/swift/pull/12318&gt](https://github.com/apple/swift/pull/12318&gt); is to  
> > create overloads that forbid the use of the elementsEqual(\_:) method  
> > specifically in non-generic code. This would prevent misuse in non-generic  
> > code; however, it would also forbid legitimate mixed-type comparisons in  
> > non-generic code while failing to prevent misuse in generic code. The  
> > solution also creates a difference in the behavior of generic and  
> > non-generic code calling the same method, which is potentially confusing,  
> > without solving the problem completely.
> > 
> > A third solution is to dramatically overhaul the protocol hierarchy for  
> > Swift sequences and collections so that unordered collections no longer  
> > have members such as first and elementsEqual(\_:). However, this would be  
> > a colossal and source-breaking undertaking, and it is unlikely to be  
> > satisfactory in addressing all the axes of differences among sequence and  
> > collection types:
> > 
> > &nbsp;&nbsp;&nbsp;- Finite versus infinite  
> > &nbsp;&nbsp;&nbsp;- Single-pass versus multi-pass  
> > &nbsp;&nbsp;&nbsp;- Ordered versus unordered  
> > &nbsp;&nbsp;&nbsp;- Lazy versus eager  
> > &nbsp;&nbsp;&nbsp;- Forward/bidirectional/random-access
> > 
> > A fourth solution is proposed here. It is predicated on the following  
> > observation:
> > 
> > \*Another method similar to elementsEqual(\_:) already exists on Sequence  
> > named lexicographicallyPrecedes(\_:). Like first, elementsEqual(\_:),  
> > drop(while:), and others, it relies on the internal order of elements in a  
> > manner that is not completely suitable for an unordered collection.  
> > However, like first and unlike elementsEqual(\_:), this fact is called out  
> > in the name of the method; unsurprisingly, like first and unlike  
> > elementsEqual(\_:), there is no evidence that lexicographicallyPrecedes(\_:)  
> > has been a pitfall for users.\*
> > 
> > This observation suggests that a major reason for confusion over  
> > elementsEqual(\_:) stems from its name. So, \*it is proposed that  
> > elementsEqual(\_:) should be renamed to lexicographicallyEquals(\_:)\*. The  
> > function will remain somewhat of a poor fit for unordered collections, but  
> > no more so than many other methods that cannot trivially be removed from  
> > the API of unordered collections (as discussed above). The key is that,  
> > with such a renaming, the behavior of this method will no longer be  
> > confusing.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#detailed-design&gt;Detailed)  
> > design
> > 
> > extension Sequence where Element : Equatable {  
> > &nbsp;&nbsp;@available(\*, deprecated, message: "Use '==' if possible to compare two sequences of the same type, or use 'lexicographicallyEquals' to compare two ordered sequences.")  
> > &nbsp;&nbsp;public func elementsEqual\<Other : Sequence\>(  
> > &nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
> > &nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
> > &nbsp;&nbsp;&nbsp;&nbsp;return lexicographicallyEquals(other)  
> > &nbsp;&nbsp;}
> > 
> > &nbsp;&nbsp;public func lexicographicallyEquals\<Other : Sequence\>(  
> > &nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
> > &nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
> > &nbsp;&nbsp;&nbsp;&nbsp;// The body of this method is unchanged. var iter1 = self.makeIterator()  
> > &nbsp;&nbsp;&nbsp;&nbsp;var iter2 = other.makeIterator()  
> > &nbsp;&nbsp;&nbsp;&nbsp;while true {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch (iter1.next(), iter2.next()) {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case let (e1?, e2?):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if e1 != e2 { return false }  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (\_?, nil), (nil, \_?):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (nil, nil):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;}  
> > }
> > 
> > A parallel change will be made with respect to elementsEqual(\_:by:); that  
> > is, it will be deprecated in favor of lexicographicallyEquals(\_:by:).
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#source-compatibility&gt;Source)  
> > compatibility
> > 
> > Existing code that uses elementsEqual will gain a deprecation warning.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#effect-on-abi-stability&gt;Effect)  
> > on ABI stability
> > 
> > None.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#effect-on-api-resilience&gt;Effect)  
> > on API resilience
> > 
> > This proposal adds new methods to the public API of Sequence and  
> > conforming types.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#alternatives-considered&gt;Alternatives)  
> > considered
> > 
> > It is to be noted that lexicographicallyPrecedes(\_:by:) and  
> > elementsEqual(\_:by:) are essentially the same method, since both perform  
> > a lexicographical comparison using a custom predicate. However, there is  
> > not a good unifying name. (lexicographicallyCompares(to:by:) reads  
> > poorly.) Moreover, the predicate supplied is intended to have very  
> > different semantics, and maintaining two distinct methods may be a superior  
> > fit with the typical user's mental model of the intended behavior and may  
> > also be clearer to readers of the code. Therefore, this proposal does not  
> > seek to unify the two methods; instead, elementsEqual(\_:by:) will be  
> > renamed lexicographicallyEquals(\_:by:) as detailed above.
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![adamkemp](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/adamkemp/32/3017_2.png) [@adamkemp](https://forums.swift.org/u/adamkemp)\
**Post date:** [October 13, 2017, 6:28am UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/7 "2017-10-13T06:28:49Z")

</div>

I agree that the proposed name is a poor choice. 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.

> **···**
>
> --  
> Adam Kemp
> 
> > On Oct 12, 2017, at 9:57 PM, Kevin Nattinger via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > –∞
> > 
> > 1. I strongly object to the proposed name. It doesn't make it more clear to me what the method does, and is misleading at best. Among other issues, "lexicographical" is defined as alphabet order, and (1) this method applies to objects that are not Strings, and (2) this method's behavior isn't any more well-defined for Strings, so that name is even more of a lie than the original.
> > 
> > 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'll outline the real issue in case someone has an idea for fixing it.
> > 
> > The root of the problem is that Set conforms to Sequence, but Sequence doesn't require a well-defined order. Since Set doesn'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't have well-defined or necessarily consistent results.
> > 
> > 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.
> > 
> > \* 7/12 by my count, ignoring `_*` funcs but including the `var`
> > 
> > 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.
> > 
> > I think those should be/should have been two separate protocols:
> > 
> > public protocol Iterable {  
> > &nbsp;&nbsp;associatedtype Iterator: IteratorProtocol  
> > &nbsp;&nbsp;func map\<T\>(...) -\> [T] // Iterable where .Iterator.Element == T  
> > &nbsp;&nbsp;func filter(...) -\> [Iterator.Element] // Iterable where .Iterator.Element == Self.Iterator.Element  
> > &nbsp;&nbsp;func forEach(...)  
> > &nbsp;&nbsp;func makeIterator() -\> Iterator  
> > &nbsp;&nbsp;var underestimatedCount: Int { get }  
> > }
> > 
> > public protocol Sequence: Iterable { // Maybe OrderedSequence just to make the well-defined-order requirement explicit  
> > &nbsp;&nbsp;associatedtype SubSequence  
> > &nbsp;&nbsp;func dropFirst(...) -\> SubSequence // Sequence where .Iterator.Element == Self.Iterator.Element  
> > &nbsp;&nbsp;func dropLast(...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func drop(while...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func prefix(...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func prefix(while...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func suffix(...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func split(...where...) -\> [SubSequence] // Iterable where .Iterator.Element == (Sequence where .Iterator.Element == Self.Iterator.Element)  
> > }
> > 
> > (The comments, of course, would be more sensible types once the ideas can actually be expressed in Swift)
> > 
> > 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.
> > 
> > Now, the practical matter. If this were Swift 1-\>2 or 2-\>3, I doubt there would be a significant issue with actually making this change. Unfortunately, we're well beyond that and making a change this deep is an enormous deal. So I see two ways forward.
> > 
> > 1. We could go ahead and make this separation. Although it'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.
> > 
> > 2. We could try and think of a way to make the distinction between ordered and unordered "sequences" in a less-breaking manner. Unfortunately, I don't have a good suggestion for this, but if anyone has ideas, I'm all ears. Or eyes, as the case may be.
> > 
> > > On Oct 12, 2017, at 4:24 PM, Xiaodi Wu via swift-evolution \<swift-evolution@swift.org\> wrote:
> > > 
> > > Rename Sequence.elementsEqual
> > > 
> > > Proposal: SE-NNNN  
> > > Authors: Xiaodi Wu  
> > > Review Manager: TBD  
> > > Status: Awaiting review  
> > > Introduction
> > > 
> > > The current behavior of Sequence.elementsEqual 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 Sequence.lexicographicallyEquals.
> > > 
> > > [...]
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![knatt](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/knatt/32/22335_2.png) [@knatt](https://forums.swift.org/u/knatt)\
**Post date:** [October 13, 2017, 1:20pm UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/8 "2017-10-13T13:20:26Z")

</div>

> 1. We could go ahead and make this separation. Although it'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.
> 
> 2. We could try and think of a way to make the distinction between ordered and unordered "sequences" in a less-breaking manner. Unfortunately, I don't have a good suggestion for this, but if anyone has ideas, I'm all ears. Or eyes, as the case may be.

It occurred to me, if we keep (and document) Sequence as unordered and move all the ordered methods to a new OrderedSequence, then we'd only be breaking truly broken code and we could even potentially offer a fix-it to change Sequence to OrderedSequence when we see the user using the ordered methods in places where we can see and change the generic definition.

I think I'd still prefer Iterable/Sequence as far as naming, but this may be a more acceptable change, and I'd rather have this than no change.

---

<div class="post-metadata">

**Author:** ![hartbit](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/hartbit/32/738_2.png) [@hartbit](https://forums.swift.org/u/hartbit)\
**Post date:** [October 13, 2017, 4:34am UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/9 "2017-10-13T04:34:18Z")

</div>

+1

Agree with the reasoning and that this is the best solution. It reduces the risk of confusing the function for what it’s not.

> **···**
>
> > On 13 Oct 2017, at 01:37, Kelvin Ma via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > I’ve always hated the use of the word “lexicographically” in that method 1) because lexicographically is hard to spell, and 2) because it’s weird to say that an unordered collection has a lexicographical order. But this change is probably for the best.
> > 
> > > On Thu, Oct 12, 2017 at 6:24 PM, Xiaodi Wu via swift-evolution \<swift-evolution@swift.org\> wrote:  
> > > Rename Sequence.elementsEqual
> > > 
> > > Proposal: SE-NNNN  
> > > Authors: Xiaodi Wu  
> > > Review Manager: TBD  
> > > Status: Awaiting review  
> > > Introduction
> > > 
> > > The current behavior of Sequence.elementsEqual 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 Sequence.lexicographicallyEquals.
> > > 
> > > Motivation
> > > 
> > > As outlined by Ole Begemann, use of Sequence.elementsEqual(\_:) can lead to surprising results if the sequences compared are unordered:
> > > 
> > > var set1: Set\<Int\> = Set(1...5)  
> > > var set2: Set\<Int\> = Set((1...5).reversed())
> > > 
> > > set1 == set2 // true  
> > > set1.elementsEqual(set2) // false  
> > > This result does reflect the intended and documented behavior of the elementsEqual(\_:) method, which performs a lexicographical elementwise comparison. That is, the method first compares set1.first to set2.first, then (if the two elements compare equal) compares the next element stored internally in set1 to the next element stored internally in set2, and so on.
> > > 
> > > In almost all circumstances where a set is compared to another set, or a dictionary is compared to another dictionary, users should use == instead of elementsEqual(\_:).
> > > 
> > > Proposed solution
> > > 
> > > The proposed solution is the result of an iterative process of reasoning, presented here:
> > > 
> > > The first and most obvious solution is to remove the elementsEqual(\_:) method altogether in favor of ==. This prevents its misuse. However, because elementsEqual(\_:) is a generic method on Sequence, we can use it to compare an instance of UnsafeBufferPointer\<Int\> to an instance of [Int]. This is a useful and non-redundant feature which would be eliminated if the method is removed altogether.
> > > 
> > > A second solution is to create overloads that forbid the use of the elementsEqual(\_:) method specifically in non-generic code. This would prevent misuse in non-generic code; however, it would also forbid legitimate mixed-type comparisons in non-generic code while failing to prevent misuse in generic code. The solution also creates a difference in the behavior of generic and non-generic code calling the same method, which is potentially confusing, without solving the problem completely.
> > > 
> > > A third solution is to dramatically overhaul the protocol hierarchy for Swift sequences and collections so that unordered collections no longer have members such as first and elementsEqual(\_:). However, this would be a colossal and source-breaking undertaking, and it is unlikely to be satisfactory in addressing all the axes of differences among sequence and collection types:
> > > 
> > > Finite versus infinite  
> > > Single-pass versus multi-pass  
> > > Ordered versus unordered  
> > > Lazy versus eager  
> > > Forward/bidirectional/random-access  
> > > A fourth solution is proposed here. It is predicated on the following observation:
> > > 
> > > Another method similar to elementsEqual(\_:) already exists on Sequence named lexicographicallyPrecedes(\_:). Like first, elementsEqual(\_:), drop(while:), and others, it relies on the internal order of elements in a manner that is not completely suitable for an unordered collection. However, like first and unlike elementsEqual(\_:), this fact is called out in the name of the method; unsurprisingly, like first and unlike elementsEqual(\_:), there is no evidence that lexicographicallyPrecedes(\_:) has been a pitfall for users.
> > > 
> > > This observation suggests that a major reason for confusion over elementsEqual(\_:) stems from its name. So, it is proposed that elementsEqual(\_:) should be renamed to lexicographicallyEquals(\_:). The function will remain somewhat of a poor fit for unordered collections, but no more so than many other methods that cannot trivially be removed from the API of unordered collections (as discussed above). The key is that, with such a renaming, the behavior of this method will no longer be confusing.
> > > 
> > > Detailed design
> > > 
> > > extension Sequence where Element : Equatable {  
> > > &nbsp;&nbsp;@available(\*, deprecated, message: "Use '==' if possible to compare two sequences of the same type, or use 'lexicographicallyEquals' to compare two ordered sequences.")  
> > > &nbsp;&nbsp;public func elementsEqual\<Other : Sequence\>(  
> > > &nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
> > > &nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;return lexicographicallyEquals(other)  
> > > &nbsp;&nbsp;}  
> > > &nbsp;&nbsp;  
> > > &nbsp;&nbsp;public func lexicographicallyEquals\<Other : Sequence\>(  
> > > &nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
> > > &nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;// The body of this method is unchanged.  
> > > &nbsp;&nbsp;&nbsp;&nbsp;var iter1 = self.makeIterator()  
> > > &nbsp;&nbsp;&nbsp;&nbsp;var iter2 = other.makeIterator()  
> > > &nbsp;&nbsp;&nbsp;&nbsp;while true {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch (iter1.next(), iter2.next()) {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case let (e1?, e2?):  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if e1 != e2 { return false }  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (\_?, nil), (nil, \_?):  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (nil, nil):  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > > &nbsp;&nbsp;&nbsp;&nbsp;}  
> > > &nbsp;&nbsp;}  
> > > }  
> > > A parallel change will be made with respect to elementsEqual(\_:by:); that is, it will be deprecated in favor of lexicographicallyEquals(\_:by:).
> > > 
> > > Source compatibility
> > > 
> > > Existing code that uses elementsEqual will gain a deprecation warning.
> > > 
> > > Effect on ABI stability
> > > 
> > > None.
> > > 
> > > Effect on API resilience
> > > 
> > > This proposal adds new methods to the public API of Sequence and conforming types.
> > > 
> > > Alternatives considered
> > > 
> > > It is to be noted that lexicographicallyPrecedes(\_:by:) and elementsEqual(\_:by:) are essentially the same method, since both perform a lexicographical comparison using a custom predicate. However, there is not a good unifying name. (lexicographicallyCompares(to:by:) reads poorly.) Moreover, the predicate supplied is intended to have very different semantics, and maintaining two distinct methods may be a superior fit with the typical user's mental model of the intended behavior and may also be clearer to readers of the code. Therefore, this proposal does not seek to unify the two methods; instead, elementsEqual(\_:by:) will be renamed lexicographicallyEquals(\_:by:) as detailed above.
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Michael\_Ilseman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/michael_ilseman/32/44640_2.png) [@Michael\_Ilseman](https://forums.swift.org/u/Michael_Ilseman)\
**Post date:** [October 13, 2017, 5:01pm UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/10 "2017-10-13T17:01:23Z")

</div>

> –∞
> 
> 1. I strongly object to the proposed name. It doesn't make it more clear to me what the method does, and is misleading at best. Among other issues, "lexicographical" is defined as alphabet order, and (1) this method applies to objects that are not Strings, and (2) this method's behavior isn't any more well-defined for Strings, so that name is even more of a lie than the original.

FWIW, in the context of String, "lexicographical ordering” does not imply human-written-language-alphabetical order at all, as there’s no universal alphabetical ordering for human language. I.e., such a concrete notion for Strings does not exist, not even theoretically. “Lexicographical” derives its meaning from the mathematical usage[1] which uses that term as well as “alphabet” without being restricted to human-written-language, in which it means some total ordering over a finite set.

[1] [Lexicographic order - Wikipedia](https://en.wikipedia.org/wiki/Lexicographical_order)

> **···**
>
> > On Oct 12, 2017, at 9:57 PM, Kevin Nattinger via swift-evolution \<swift-evolution@swift.org\> wrote:
> 
> > 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'll outline the real issue in case someone has an idea for fixing it.
> > 
> > The root of the problem is that Set conforms to Sequence, but Sequence doesn't require a well-defined order. Since Set doesn'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't have well-defined or necessarily consistent results.
> > 
> > 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.
> > 
> > \* 7/12 by my count, ignoring `_*` funcs but including the `var`
> > 
> > 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.
> > 
> > I think those should be/should have been two separate protocols:
> > 
> > public protocol Iterable {  
> > &nbsp;&nbsp;associatedtype Iterator: IteratorProtocol  
> > &nbsp;&nbsp;func map\<T\>(...) -\> [T] // Iterable where .Iterator.Element == T  
> > &nbsp;&nbsp;func filter(...) -\> [Iterator.Element] // Iterable where .Iterator.Element == Self.Iterator.Element  
> > &nbsp;&nbsp;func forEach(...)  
> > &nbsp;&nbsp;func makeIterator() -\> Iterator  
> > &nbsp;&nbsp;var underestimatedCount: Int { get }  
> > }
> > 
> > public protocol Sequence: Iterable { // Maybe OrderedSequence just to make the well-defined-order requirement explicit  
> > &nbsp;&nbsp;associatedtype SubSequence  
> > &nbsp;&nbsp;func dropFirst(...) -\> SubSequence // Sequence where .Iterator.Element == Self.Iterator.Element  
> > &nbsp;&nbsp;func dropLast(...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func drop(while...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func prefix(...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func prefix(while...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func suffix(...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func split(...where...) -\> [SubSequence] // Iterable where .Iterator.Element == (Sequence where .Iterator.Element == Self.Iterator.Element)  
> > }
> > 
> > (The comments, of course, would be more sensible types once the ideas can actually be expressed in Swift)
> > 
> > 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.
> > 
> > Now, the practical matter. If this were Swift 1-\>2 or 2-\>3, I doubt there would be a significant issue with actually making this change. Unfortunately, we're well beyond that and making a change this deep is an enormous deal. So I see two ways forward.
> > 
> > 1. We could go ahead and make this separation. Although it'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.
> > 
> > 2. We could try and think of a way to make the distinction between ordered and unordered "sequences" in a less-breaking manner. Unfortunately, I don't have a good suggestion for this, but if anyone has ideas, I'm all ears. Or eyes, as the case may be.
> > 
> > > On Oct 12, 2017, at 4:24 PM, Xiaodi Wu via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> > > 
> > > Rename Sequence.elementsEqual
> > > 
> > > Proposal: SE-NNNN \<[https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt](https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt);  
> > > Authors: Xiaodi Wu \<[https://github.com/xwu&gt](https://github.com/xwu&gt);  
> > > Review Manager: TBD  
> > > Status: Awaiting review  
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#introduction&gt;Introduction)
> > > 
> > > The current behavior of Sequence.elementsEqual 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 Sequence.lexicographicallyEquals.
> > > 
> > > [...]
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Jon\_Hull](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_hull/32/678_2.png) [@Jon\_Hull](https://forums.swift.org/u/Jon_Hull)\
**Post date:** [October 13, 2017, 8:06pm UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/11 "2017-10-13T20:06:21Z")

</div>

It has been a while, but I believe a lexicographical ordering is basically a mapping from a set to the natural numbers (which should, in effect, provide a total ordering). The mapping itself can be arbitrary, but the same set of things should never map to two different sequences (which just happens to be the example given).

This tells me that “lexicographicallyPrecedes” is actually misnamed unless it refers to something which has a defined totally ordering.

If we are looking to rename elementsEqual (which I would expect to check if the same elements are present regardless of ordering), I would recommend elementOrderingEqual or something like that that references that the answer will be affected by the internal representation/ordering of the sequence.

Thanks,  
Jon

> **···**
>
> > On Oct 13, 2017, at 11:10 AM, Jarod Long via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > The name that feels natural to me would be `sequentiallyEquals`. I don't dispute that the term "lexicographical" is used correctly here, although at least for me personally, it's not a word that I encounter frequently enough to understand what this method would do without reading the documentation. Like Kevin, if I were to guess what the method did without checking, I would probably think that it compared lexicographically-sorted versions of the collections.
> > 
> > But the consistency with `lexicographicallyPrecedes` is a pretty strong argument, although `sequentiallyPrecedes` would also feel more natural to me there, and my suspicion about the mentioned lack of evidence that the method has been a pitfall for users is that it's not actually used often enough out in the wild to have heard much about it. That's just a guess though. This proposal is the first time I've learned of its existence.
> > 
> > In any case, my ideal version of this proposal would use `sequentiallyEquals` and also rename `lexicographicallyPrecedes` to `sequentiallyPrecedes`, but I still like the proposal overall as-is. Thanks for bringing it forward!
> > 
> > Jarod
> > 
> > On Oct 12, 2017, 16:24 -0700, Xiaodi Wu via swift-evolution \<swift-evolution@swift.org\>, wrote:
> > 
> > > Rename Sequence.elementsEqual
> > > 
> > > Proposal: SE-NNNN \<[https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt](https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt);  
> > > Authors: Xiaodi Wu \<[https://github.com/xwu&gt](https://github.com/xwu&gt);  
> > > Review Manager: TBD  
> > > Status: Awaiting review  
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#introduction&gt;Introduction)
> > > 
> > > The current behavior of Sequence.elementsEqual 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 Sequence.lexicographicallyEquals.
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#motivation&gt;Motivation)
> > > 
> > > As outlined by Ole Begemann \<[https://twitter.com/olebegemann/status/916291785185529857&gt;](https://twitter.com/olebegemann/status/916291785185529857&gt;), use of Sequence.elementsEqual(\_:) can lead to surprising results if the sequences compared are unordered:
> > > 
> > > var set1: Set\<Int\> = Set(1...5)  
> > > var set2: Set\<Int\> = Set((1...5).reversed())
> > > 
> > > set1 == set2 // true  
> > > set1.elementsEqual(set2) // false  
> > > This result does reflect the intended and documented behavior of the elementsEqual(\_:) method, which performs a lexicographical elementwise comparison. That is, the method first compares set1.first to set2.first, then (if the two elements compare equal) compares the next element stored internally in set1 to the next element stored internally in set2, and so on.
> > > 
> > > In almost all circumstances where a set is compared to another set, or a dictionary is compared to another dictionary, users should use == instead of elementsEqual(\_:).
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#proposed-solution&gt;Proposed) solution
> > > 
> > > The proposed solution is the result of an iterative process of reasoning, presented here:
> > > 
> > > The first and most obvious solution is to remove the elementsEqual(\_:) method altogether in favor of ==. This prevents its misuse. However, because elementsEqual(\_:) is a generic method on Sequence, we can use it to compare an instance of UnsafeBufferPointer\<Int\> to an instance of [Int]. This is a useful and non-redundant feature which would be eliminated if the method is removed altogether.
> > > 
> > > A second solution \<[https://github.com/apple/swift/pull/12318&gt](https://github.com/apple/swift/pull/12318&gt); is to create overloads that forbid the use of the elementsEqual(\_:) method specifically in non-generic code. This would prevent misuse in non-generic code; however, it would also forbid legitimate mixed-type comparisons in non-generic code while failing to prevent misuse in generic code. The solution also creates a difference in the behavior of generic and non-generic code calling the same method, which is potentially confusing, without solving the problem completely.
> > > 
> > > A third solution is to dramatically overhaul the protocol hierarchy for Swift sequences and collections so that unordered collections no longer have members such as first and elementsEqual(\_:). However, this would be a colossal and source-breaking undertaking, and it is unlikely to be satisfactory in addressing all the axes of differences among sequence and collection types:
> > > 
> > > Finite versus infinite  
> > > Single-pass versus multi-pass  
> > > Ordered versus unordered  
> > > Lazy versus eager  
> > > Forward/bidirectional/random-access  
> > > A fourth solution is proposed here. It is predicated on the following observation:
> > > 
> > > Another method similar to elementsEqual(\_:) already exists on Sequence named lexicographicallyPrecedes(\_:). Like first, elementsEqual(\_:), drop(while:), and others, it relies on the internal order of elements in a manner that is not completely suitable for an unordered collection. However, like first and unlike elementsEqual(\_:), this fact is called out in the name of the method; unsurprisingly, like first and unlike elementsEqual(\_:), there is no evidence that lexicographicallyPrecedes(\_:) has been a pitfall for users.
> > > 
> > > This observation suggests that a major reason for confusion over elementsEqual(\_:) stems from its name. So, it is proposed that elementsEqual(\_:) should be renamed to lexicographicallyEquals(\_:). The function will remain somewhat of a poor fit for unordered collections, but no more so than many other methods that cannot trivially be removed from the API of unordered collections (as discussed above). The key is that, with such a renaming, the behavior of this method will no longer be confusing.
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#detailed-design&gt;Detailed) design
> > > 
> > > extension Sequence where Element : Equatable {  
> > > &nbsp;&nbsp;@available(\*, deprecated, message: "Use '==' if possible to compare two sequences of the same type, or use 'lexicographicallyEquals' to compare two ordered sequences.")  
> > > &nbsp;&nbsp;public func elementsEqual\<Other : Sequence\>(  
> > > &nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
> > > &nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;return lexicographicallyEquals(other)  
> > > &nbsp;&nbsp;}  
> > > &nbsp;&nbsp;&nbsp;  
> > > &nbsp;&nbsp;public func lexicographicallyEquals\<Other : Sequence\>(  
> > > &nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
> > > &nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;// The body of this method is unchanged.  
> > > &nbsp;&nbsp;&nbsp;&nbsp;var iter1 = self.makeIterator()  
> > > &nbsp;&nbsp;&nbsp;&nbsp;var iter2 = other.makeIterator()  
> > > &nbsp;&nbsp;&nbsp;&nbsp;while true {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch (iter1.next(), iter2.next()) {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case let (e1?, e2?):  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if e1 != e2 { return false }  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (\_?, nil), (nil, \_?):  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (nil, nil):  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > > &nbsp;&nbsp;&nbsp;&nbsp;}  
> > > &nbsp;&nbsp;}  
> > > }  
> > > A parallel change will be made with respect to elementsEqual(\_:by:); that is, it will be deprecated in favor of lexicographicallyEquals(\_:by:).
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#source-compatibility&gt;Source) compatibility
> > > 
> > > Existing code that uses elementsEqual will gain a deprecation warning.
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#effect-on-abi-stability&gt;Effect) on ABI stability
> > > 
> > > None.
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#effect-on-api-resilience&gt;Effect) on API resilience
> > > 
> > > This proposal adds new methods to the public API of Sequence and conforming types.
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#alternatives-considered&gt;Alternatives) considered
> > > 
> > > It is to be noted that lexicographicallyPrecedes(\_:by:) and elementsEqual(\_:by:) are essentially the same method, since both perform a lexicographical comparison using a custom predicate. However, there is not a good unifying name. (lexicographicallyCompares(to:by:) reads poorly.) Moreover, the predicate supplied is intended to have very different semantics, and maintaining two distinct methods may be a superior fit with the typical user's mental model of the intended behavior and may also be clearer to readers of the code. Therefore, this proposal does not seek to unify the two methods; instead, elementsEqual(\_:by:) will be renamed lexicographicallyEquals(\_:by:) as detailed above.
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![benjamin.g](https://avatars.discourse-cdn.com/v4/letter/b/9fc29f/32.png) [@benjamin.g](https://forums.swift.org/u/benjamin.g)\
**Post date:** [October 13, 2017, 12:09pm UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/12 "2017-10-13T12:09:52Z")

</div>

+1 on both points. As for your solutions, i see 1/ as the best solution.  
Breaking source code that rely on badly defined, or improper behavior isn't  
"breaking". You don't break something that's already half broken.  
As an app developer relying on swift on my day to day job and making a  
living of it, i want to emphasis this: I really don't mind if a language  
version change is making me look more carefully on some parts of my code  
that i probably had overlooked.  
Sure i may pester a bit when the code doesn't compile, but it sure is  
better than discovering the weird behavior of a badly defined protocol  
hierarchy in customer support.

> **···**
>
> On Fri, Oct 13, 2017 at 6:57 AM, Kevin Nattinger via swift-evolution \< swift-evolution@swift.org\> wrote:
> 
> > –∞
> > 
> > 1. I strongly object to the proposed name. It doesn't make it more clear  
> > to me what the method does, and is misleading at best. Among other issues,  
> > "lexicographical" is defined as alphabet order, and (1) this method applies  
> > to objects that are not Strings, and (2) this method's behavior isn't any  
> > more well-defined for Strings, so that name is even more of a lie than the  
> > original.
> > 
> > 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'll outline the real issue  
> > in case someone has an idea for fixing it.
> > 
> > \*The root of the problem is that Set conforms to Sequence, but Sequence  
> > doesn't require a well-defined order.\* Since Set doesn'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't have  
> > well-defined or necessarily consistent results.
> > 
> > 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.
> > 
> > \* 7/12 by my count, ignoring `_*` funcs but including the `var`
> > 
> > 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.
> > 
> > I think those should be/should have been two separate protocols:
> > 
> > public protocol Iterable {  
> > &nbsp;&nbsp;associatedtype Iterator: IteratorProtocol  
> > &nbsp;&nbsp;func map\<T\>(...) -\> [T] // Iterable where .Iterator.Element == T  
> > &nbsp;&nbsp;func filter(...) -\> [Iterator.Element] // Iterable where  
> > .Iterator.Element == Self.Iterator.Element  
> > &nbsp;&nbsp;func forEach(...)  
> > &nbsp;&nbsp;func makeIterator() -\> Iterator  
> > &nbsp;&nbsp;var underestimatedCount: Int { get }  
> > }
> > 
> > public protocol Sequence: Iterable { // Maybe OrderedSequence just to  
> > make the well-defined-order requirement explicit  
> > &nbsp;&nbsp;associatedtype SubSequence  
> > &nbsp;&nbsp;func dropFirst(...) -\> SubSequence // Sequence where  
> > .Iterator.Element == Self.Iterator.Element  
> > &nbsp;&nbsp;func dropLast(...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func drop(while...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func prefix(...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func prefix(while...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func suffix(...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func split(...where...) -\> [SubSequence] // Iterable where  
> > .Iterator.Element == (Sequence where .Iterator.Element ==  
> > Self.Iterator.Element)  
> > }
> > 
> > (The comments, of course, would be more sensible types once the ideas can  
> > actually be expressed in Swift)
> > 
> > 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.
> > 
> > Now, the practical matter. If this were Swift 1-\>2 or 2-\>3, I doubt there  
> > would be a significant issue with actually making this change.  
> > Unfortunately, we're well beyond that and making a change this  
> > deep is an enormous deal. So I see two ways forward.
> > 
> > 1. We could go ahead and make this separation. Although it'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.
> > 
> > 2. We could try and think of a way to make the distinction between ordered  
> > and unordered "sequences" in a less-breaking manner. Unfortunately, I don't  
> > have a good suggestion for this, but if anyone has ideas, I'm all ears. Or  
> > eyes, as the case may be.
> > 
> > On Oct 12, 2017, at 4:24 PM, Xiaodi Wu via swift-evolution \< \> swift-evolution@swift.org\> wrote:
> > 
> > Rename Sequence.elementsEqual
> > 
> > &nbsp;&nbsp;&nbsp;- Proposal: SE-NNNN  
> > &nbsp;&nbsp;&nbsp;\<[https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt](https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt);  
> > &nbsp;&nbsp;&nbsp;- Authors: Xiaodi Wu \<[https://github.com/xwu&gt](https://github.com/xwu&gt);  
> > &nbsp;&nbsp;&nbsp;- Review Manager: TBD  
> > &nbsp;&nbsp;&nbsp;- Status: \*Awaiting review\*
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#introduction&gt);  
> > Introduction
> > 
> > The current behavior of Sequence.elementsEqual 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 Sequence.  
> > lexicographicallyEquals.  
> > [...]
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Brent\_Royal-Gordon](https://avatars.discourse-cdn.com/v4/letter/b/53a042/32.png) [@Brent\_Royal-Gordon](https://forums.swift.org/u/Brent_Royal-Gordon)\
**Post date:** [October 14, 2017, 1:45am UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/13 "2017-10-14T01:45:16Z")

</div>

It means to skip the first element the set would normally have given you. Which element this will be may be arbitrary, but this is still not useless:

&nbsp;&nbsp;&nbsp;&nbsp;set.dropFirst().reduce(set.first!, …)

Even elementsEqual(\_:) does tell you something potentially valuable: Whether two instances will end up giving the same result when processed by an ordering-sensitive algorithm.

We should change the name to something like orderEquals(\_:), and maybe change the lexicographicallyPrecedes(\_:) method to something analogous like orderPrecedes(\_:), and then be done with it.

> **···**
>
> > On Oct 12, 2017, at 9:57 PM, Kevin Nattinger via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > 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?
> 
> --  
> Brent Royal-Gordon  
> Sent from my iPhone

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [October 14, 2017, 3:56am UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/14 "2017-10-14T03:56:57Z")

</div>

> Using the term “lexicographically” implies to me that the Element type  
> must conform to Comparable, as would be required for a total order. The  
> Sequence method you mention, lexicographicallyPrecedes(\_:), does have this  
> constraint, whereas the method in question for elementsEqual(\_:) /  
> lexicographicallyEquals(\_:) only has the constraint that the Element is  
> Equatable. As an example, an array of simple enums has no default  
> lexicographical ordering but is still able to use this method because enums  
> (without associated values) are Equatable by default:
> 
> \*enum\* Foo {  
> &nbsp;&nbsp;&nbsp;&nbsp;\*case\* bar  
> &nbsp;&nbsp;&nbsp;&nbsp;\*case\* baz  
> }
> 
> \*let\* f1 = [Foo.bar, Foo.baz]  
> \*let\* f2 = [Foo.baz, Foo.bar]
> 
> f1.elementsEqual(f2) //false  
> f1.elementsEqual(f2.reversed()) //true
> 
> I also share Jonathan’s concerns that some programmers may misinterpret  
> [lexicographically][Equals] to mean [sorted in lexicographical  
> order][compare sequence equality], which is not what the method in question  
> does.
> 
> Xiaodi, I think you are right that Sequence.sequentiallyEquals is to close  
> to "==" to use, but I think we have to find something better here.
> 
> I’ll recommend that we use the name \*Sequence.iterativelyEquals(\_:)\* since  
> this describes the body of the method concisely. A rough abbreviation of  
> this algorithm is:
> 
> 1. Iterate over elements in two sequences  
> a. Compare elements for equality
> 
> “iterativelyEquals" concisely describes this.

That's an intriguing alternative. The key quality to be communicated,  
practically speaking, is that if two instances `x` and `y` compare `true`  
with `elementsEqual`, then `for i in x { ... }` and `for i in y { ... }`  
should be substitutable (if the elements of `x` and `y` are not consumed on  
the first iteration), because the semantics of `Equatable` demand that  
"equivalence means substitutability." This would be captured by something  
like the name you suggest, or to be even more explicit:

```swift
x.substitutesForThePurposesOfIteratedAccess(for: y)

```

This is intentionally unwieldy to attract others to try to do better :) But  
I think it captures the meaning we are going for here.

> **···**
>
> On Fri, Oct 13, 2017 at 4:52 PM, Christopher Whidden \< christopher.whidden@gmail.com\> wrote:
> 
> > On Oct 12, 2017, at 6:24 PM, Xiaodi Wu via swift-evolution \< \> swift-evolution@swift.org\> wrote:
> > 
> > Rename Sequence.elementsEqual
> > 
> > &nbsp;&nbsp;&nbsp;- Proposal: SE-NNNN  
> > &nbsp;&nbsp;&nbsp;\<[https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt](https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt);  
> > &nbsp;&nbsp;&nbsp;- Authors: Xiaodi Wu \<[https://github.com/xwu&gt](https://github.com/xwu&gt);  
> > &nbsp;&nbsp;&nbsp;- Review Manager: TBD  
> > &nbsp;&nbsp;&nbsp;- Status: \*Awaiting review\*
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#introduction&gt);  
> > Introduction
> > 
> > The current behavior of Sequence.elementsEqual 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 Sequence.  
> > lexicographicallyEquals.  
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#motivation&gt);  
> > Motivation
> > 
> > As outlined by Ole Begemann  
> > \<[https://twitter.com/olebegemann/status/916291785185529857&gt;](https://twitter.com/olebegemann/status/916291785185529857&gt;), use of  
> > Sequence.elementsEqual(\_:) can lead to surprising results if the  
> > sequences compared are unordered:
> > 
> > var set1: Set\<Int\> = Set(1...5)var set2: Set\<Int\> = Set((1...5).reversed())
> > 
> > set1 == set2 // trueset1.elementsEqual(set2) // false
> > 
> > This result does reflect the \*intended and documented\* behavior of the  
> > elementsEqual(\_:) method, which performs a \*lexicographical\* elementwise  
> > comparison. That is, the method first compares set1.first to set2.first,  
> > then (if the two elements compare equal) compares the next element stored  
> > internally in set1 to the next element stored internally in set2, and so  
> > on.
> > 
> > In almost all circumstances where a set is compared to another set, or a  
> > dictionary is compared to another dictionary, users should use == instead  
> > of elementsEqual(\_:).
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#proposed-solution&gt;Proposed)  
> > solution
> > 
> > The proposed solution is the result of an iterative process of reasoning,  
> > presented here:
> > 
> > The first and most obvious solution is to remove the elementsEqual(\_:)  
> > method altogether in favor of ==. This prevents its misuse. However,  
> > because elementsEqual(\_:) is a generic method on Sequence, we can use it  
> > to compare an instance of UnsafeBufferPointer\<Int\> to an instance of [Int].  
> > This is a useful and non-redundant feature which would be eliminated if the  
> > method is removed altogether.
> > 
> > A second solution \<[https://github.com/apple/swift/pull/12318&gt](https://github.com/apple/swift/pull/12318&gt); is to  
> > create overloads that forbid the use of the elementsEqual(\_:) method  
> > specifically in non-generic code. This would prevent misuse in non-generic  
> > code; however, it would also forbid legitimate mixed-type comparisons in  
> > non-generic code while failing to prevent misuse in generic code. The  
> > solution also creates a difference in the behavior of generic and  
> > non-generic code calling the same method, which is potentially confusing,  
> > without solving the problem completely.
> > 
> > A third solution is to dramatically overhaul the protocol hierarchy for  
> > Swift sequences and collections so that unordered collections no longer  
> > have members such as first and elementsEqual(\_:). However, this would be  
> > a colossal and source-breaking undertaking, and it is unlikely to be  
> > satisfactory in addressing all the axes of differences among sequence and  
> > collection types:
> > 
> > &nbsp;&nbsp;&nbsp;- Finite versus infinite  
> > &nbsp;&nbsp;&nbsp;- Single-pass versus multi-pass  
> > &nbsp;&nbsp;&nbsp;- Ordered versus unordered  
> > &nbsp;&nbsp;&nbsp;- Lazy versus eager  
> > &nbsp;&nbsp;&nbsp;- Forward/bidirectional/random-access
> > 
> > A fourth solution is proposed here. It is predicated on the following  
> > observation:
> > 
> > \*Another method similar to elementsEqual(\_:) already exists on Sequence  
> > named lexicographicallyPrecedes(\_:). Like first, elementsEqual(\_:),  
> > drop(while:), and others, it relies on the internal order of elements in a  
> > manner that is not completely suitable for an unordered collection.  
> > However, like first and unlike elementsEqual(\_:), this fact is called out  
> > in the name of the method; unsurprisingly, like first and unlike  
> > elementsEqual(\_:), there is no evidence that lexicographicallyPrecedes(\_:)  
> > has been a pitfall for users.\*
> > 
> > This observation suggests that a major reason for confusion over  
> > elementsEqual(\_:) stems from its name. So, \*it is proposed that  
> > elementsEqual(\_:) should be renamed to lexicographicallyEquals(\_:)\*. The  
> > function will remain somewhat of a poor fit for unordered collections, but  
> > no more so than many other methods that cannot trivially be removed from  
> > the API of unordered collections (as discussed above). The key is that,  
> > with such a renaming, the behavior of this method will no longer be  
> > confusing.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#detailed-design&gt;Detailed)  
> > design
> > 
> > extension Sequence where Element : Equatable {  
> > &nbsp;&nbsp;@available(\*, deprecated, message: "Use '==' if possible to compare two sequences of the same type, or use 'lexicographicallyEquals' to compare two ordered sequences.")  
> > &nbsp;&nbsp;public func elementsEqual\<Other : Sequence\>(  
> > &nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
> > &nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
> > &nbsp;&nbsp;&nbsp;&nbsp;return lexicographicallyEquals(other)  
> > &nbsp;&nbsp;}
> > 
> > &nbsp;&nbsp;public func lexicographicallyEquals\<Other : Sequence\>(  
> > &nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
> > &nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
> > &nbsp;&nbsp;&nbsp;&nbsp;// The body of this method is unchanged. var iter1 = self.makeIterator()  
> > &nbsp;&nbsp;&nbsp;&nbsp;var iter2 = other.makeIterator()  
> > &nbsp;&nbsp;&nbsp;&nbsp;while true {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch (iter1.next(), iter2.next()) {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case let (e1?, e2?):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if e1 != e2 { return false }  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (\_?, nil), (nil, \_?):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (nil, nil):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;}  
> > }
> > 
> > A parallel change will be made with respect to elementsEqual(\_:by:); that  
> > is, it will be deprecated in favor of lexicographicallyEquals(\_:by:).
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#source-compatibility&gt;Source)  
> > compatibility
> > 
> > Existing code that uses elementsEqual will gain a deprecation warning.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#effect-on-abi-stability&gt;Effect)  
> > on ABI stability
> > 
> > None.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#effect-on-api-resilience&gt;Effect)  
> > on API resilience
> > 
> > This proposal adds new methods to the public API of Sequence and  
> > conforming types.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#alternatives-considered&gt;Alternatives)  
> > considered
> > 
> > It is to be noted that lexicographicallyPrecedes(\_:by:) and  
> > elementsEqual(\_:by:) are essentially the same method, since both perform  
> > a lexicographical comparison using a custom predicate. However, there is  
> > not a good unifying name. (lexicographicallyCompares(to:by:) reads  
> > poorly.) Moreover, the predicate supplied is intended to have very  
> > different semantics, and maintaining two distinct methods may be a superior  
> > fit with the typical user's mental model of the intended behavior and may  
> > also be clearer to readers of the code. Therefore, this proposal does not  
> > seek to unify the two methods; instead, elementsEqual(\_:by:) will be  
> > renamed lexicographicallyEquals(\_:by:) as detailed above.  
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![trs](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/trs/32/2038_2.png) [@trs](https://forums.swift.org/u/trs)\
**Post date:** [October 14, 2017, 1:32pm UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/15 "2017-10-14T13:32:36Z")

</div>

Totally agree with Kevin’s analysis. I always thought „Sequence“ a very misleading name for an Iterable.  
I wouldn’t mind the breakage at all.

-Thorsten

> **···**
>
> > Am 13.10.2017 um 06:57 schrieb Kevin Nattinger via swift-evolution \<swift-evolution@swift.org\>:
> > 
> > –∞
> > 
> > 1. I strongly object to the proposed name. It doesn't make it more clear to me what the method does, and is misleading at best. Among other issues, "lexicographical" is defined as alphabet order, and (1) this method applies to objects that are not Strings, and (2) this method's behavior isn't any more well-defined for Strings, so that name is even more of a lie than the original.
> > 
> > 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'll outline the real issue in case someone has an idea for fixing it.
> > 
> > The root of the problem is that Set conforms to Sequence, but Sequence doesn't require a well-defined order. Since Set doesn'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't have well-defined or necessarily consistent results.
> > 
> > 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.
> > 
> > \* 7/12 by my count, ignoring `_*` funcs but including the `var`
> > 
> > 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.
> > 
> > I think those should be/should have been two separate protocols:
> > 
> > public protocol Iterable {  
> > &nbsp;&nbsp;associatedtype Iterator: IteratorProtocol  
> > &nbsp;&nbsp;func map\<T\>(...) -\> [T] // Iterable where .Iterator.Element == T  
> > &nbsp;&nbsp;func filter(...) -\> [Iterator.Element] // Iterable where .Iterator.Element == Self.Iterator.Element  
> > &nbsp;&nbsp;func forEach(...)  
> > &nbsp;&nbsp;func makeIterator() -\> Iterator  
> > &nbsp;&nbsp;var underestimatedCount: Int { get }  
> > }
> > 
> > public protocol Sequence: Iterable { // Maybe OrderedSequence just to make the well-defined-order requirement explicit  
> > &nbsp;&nbsp;associatedtype SubSequence  
> > &nbsp;&nbsp;func dropFirst(...) -\> SubSequence // Sequence where .Iterator.Element == Self.Iterator.Element  
> > &nbsp;&nbsp;func dropLast(...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func drop(while...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func prefix(...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func prefix(while...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func suffix(...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func split(...where...) -\> [SubSequence] // Iterable where .Iterator.Element == (Sequence where .Iterator.Element == Self.Iterator.Element)  
> > }
> > 
> > (The comments, of course, would be more sensible types once the ideas can actually be expressed in Swift)
> > 
> > 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.
> > 
> > Now, the practical matter. If this were Swift 1-\>2 or 2-\>3, I doubt there would be a significant issue with actually making this change. Unfortunately, we're well beyond that and making a change this deep is an enormous deal. So I see two ways forward.
> > 
> > 1. We could go ahead and make this separation. Although it'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.
> > 
> > 2. We could try and think of a way to make the distinction between ordered and unordered "sequences" in a less-breaking manner. Unfortunately, I don't have a good suggestion for this, but if anyone has ideas, I'm all ears. Or eyes, as the case may be.
> > 
> > > On Oct 12, 2017, at 4:24 PM, Xiaodi Wu via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> > > 
> > > Rename Sequence.elementsEqual
> > > 
> > > Proposal: SE-NNNN \<[https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt](https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt);  
> > > Authors: Xiaodi Wu \<[https://github.com/xwu&gt](https://github.com/xwu&gt);  
> > > Review Manager: TBD  
> > > Status: Awaiting review  
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#introduction&gt;Introduction)
> > > 
> > > The current behavior of Sequence.elementsEqual 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 Sequence.lexicographicallyEquals.
> > > 
> > > [...]
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Michael\_Ilseman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/michael_ilseman/32/44640_2.png) [@Michael\_Ilseman](https://forums.swift.org/u/Michael_Ilseman)\
**Post date:** [October 15, 2017, 1:11am UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/16 "2017-10-15T01:11:48Z")

</div>

I think that “match” is a word to avoid for this, as this doesn’t have anything to do with pattern matching, fuzzy matching, etc., while “equals” is precisely the concept we’re using.

What about the name “sequentiallyEquals”? Highlight the fact that we’re talking about sequential ordering, i.e. whatever order the sequence provides, as opposed to first doing some lexicographical ordering of elements themselves.

var a: Set\<Int\> = [3, 1, 2]  
a.sequentiallyEquals([1,2,3]) // result depends on application of equality in a (potentially-arbitrary) sequential ordering

Whereas I could see the following being more confusing:

var a: Set\<Int\> = [3, 1, 2]  
a.lexicographicallyEquals([1,2,3]) // result depends on application of equality, but what meaning does “lexicographically” convey?

It’s not immediately clear to someone new to the API that “lexicographically” speaks to the nature of the sequence’s (potentially-arbitrary) order, irrespective of element. It could give the false impression that it speaks to some nature of the elements themselves, in this case Ints, which have an obvious lexicographical ordering. I don’t know how frequent that misconception would be in practice, but it does cause me to do a double-take in this contrived example.

> **···**
>
> > On Oct 14, 2017, at 1:04 PM, Benjamin G via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > To answer more precisely this request (which remains valid no matter the protocol hierarchy). I propose
> > 
> > "matchesSequence" ( or simply "matches" or "match", whatever is more coherent with the naming guidelines).
> > 
> > So  
> > var a: [Int] = [1,2,3]  
> > a.matchesSequence([1,2,3]) returns true.
> > 
> > I first thought that the verb "matching" was too heavily associated to regular expressions, but i think that it's the correct equivalent for something as general as a sequence.
> > 
> > On Fri, Oct 13, 2017 at 1:24 AM, Xiaodi Wu via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:  
> > Rename Sequence.elementsEqual
> > 
> > Proposal: SE-NNNN \<[https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt](https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt);  
> > Authors: Xiaodi Wu \<[https://github.com/xwu&gt](https://github.com/xwu&gt);  
> > Review Manager: TBD  
> > Status: Awaiting review  
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#introduction&gt;Introduction)
> > 
> > The current behavior of Sequence.elementsEqual 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 Sequence.lexicographicallyEquals.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#motivation&gt;Motivation)
> > 
> > As outlined by Ole Begemann \<[https://twitter.com/olebegemann/status/916291785185529857&gt;](https://twitter.com/olebegemann/status/916291785185529857&gt;), use of Sequence.elementsEqual(\_:) can lead to surprising results if the sequences compared are unordered:
> > 
> > var set1: Set\<Int\> = Set(1...5)  
> > var set2: Set\<Int\> = Set((1...5).reversed())
> > 
> > set1 == set2 // true  
> > set1.elementsEqual(set2) // false  
> > This result does reflect the intended and documented behavior of the elementsEqual(\_:) method, which performs a lexicographical elementwise comparison. That is, the method first compares set1.first to set2.first, then (if the two elements compare equal) compares the next element stored internally in set1 to the next element stored internally in set2, and so on.
> > 
> > In almost all circumstances where a set is compared to another set, or a dictionary is compared to another dictionary, users should use == instead of elementsEqual(\_:).
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#proposed-solution&gt;Proposed) solution
> > 
> > The proposed solution is the result of an iterative process of reasoning, presented here:
> > 
> > The first and most obvious solution is to remove the elementsEqual(\_:) method altogether in favor of ==. This prevents its misuse. However, because elementsEqual(\_:) is a generic method on Sequence, we can use it to compare an instance of UnsafeBufferPointer\<Int\> to an instance of [Int]. This is a useful and non-redundant feature which would be eliminated if the method is removed altogether.
> > 
> > A second solution \<[https://github.com/apple/swift/pull/12318&gt](https://github.com/apple/swift/pull/12318&gt); is to create overloads that forbid the use of the elementsEqual(\_:) method specifically in non-generic code. This would prevent misuse in non-generic code; however, it would also forbid legitimate mixed-type comparisons in non-generic code while failing to prevent misuse in generic code. The solution also creates a difference in the behavior of generic and non-generic code calling the same method, which is potentially confusing, without solving the problem completely.
> > 
> > A third solution is to dramatically overhaul the protocol hierarchy for Swift sequences and collections so that unordered collections no longer have members such as first and elementsEqual(\_:). However, this would be a colossal and source-breaking undertaking, and it is unlikely to be satisfactory in addressing all the axes of differences among sequence and collection types:
> > 
> > Finite versus infinite  
> > Single-pass versus multi-pass  
> > Ordered versus unordered  
> > Lazy versus eager  
> > Forward/bidirectional/random-access  
> > A fourth solution is proposed here. It is predicated on the following observation:
> > 
> > Another method similar to elementsEqual(\_:) already exists on Sequence named lexicographicallyPrecedes(\_:). Like first, elementsEqual(\_:), drop(while:), and others, it relies on the internal order of elements in a manner that is not completely suitable for an unordered collection. However, like first and unlike elementsEqual(\_:), this fact is called out in the name of the method; unsurprisingly, like first and unlike elementsEqual(\_:), there is no evidence that lexicographicallyPrecedes(\_:) has been a pitfall for users.
> > 
> > This observation suggests that a major reason for confusion over elementsEqual(\_:) stems from its name. So, it is proposed that elementsEqual(\_:) should be renamed to lexicographicallyEquals(\_:). The function will remain somewhat of a poor fit for unordered collections, but no more so than many other methods that cannot trivially be removed from the API of unordered collections (as discussed above). The key is that, with such a renaming, the behavior of this method will no longer be confusing.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#detailed-design&gt;Detailed) design
> > 
> > extension Sequence where Element : Equatable {  
> > &nbsp;&nbsp;@available(\*, deprecated, message: "Use '==' if possible to compare two sequences of the same type, or use 'lexicographicallyEquals' to compare two ordered sequences.")  
> > &nbsp;&nbsp;public func elementsEqual\<Other : Sequence\>(  
> > &nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
> > &nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
> > &nbsp;&nbsp;&nbsp;&nbsp;return lexicographicallyEquals(other)  
> > &nbsp;&nbsp;}  
> > &nbsp;&nbsp;  
> > &nbsp;&nbsp;public func lexicographicallyEquals\<Other : Sequence\>(  
> > &nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
> > &nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
> > &nbsp;&nbsp;&nbsp;&nbsp;// The body of this method is unchanged.  
> > &nbsp;&nbsp;&nbsp;&nbsp;var iter1 = self.makeIterator()  
> > &nbsp;&nbsp;&nbsp;&nbsp;var iter2 = other.makeIterator()  
> > &nbsp;&nbsp;&nbsp;&nbsp;while true {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch (iter1.next(), iter2.next()) {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case let (e1?, e2?):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if e1 != e2 { return false }  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (\_?, nil), (nil, \_?):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (nil, nil):  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;}  
> > }  
> > A parallel change will be made with respect to elementsEqual(\_:by:); that is, it will be deprecated in favor of lexicographicallyEquals(\_:by:).
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#source-compatibility&gt;Source) compatibility
> > 
> > Existing code that uses elementsEqual will gain a deprecation warning.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#effect-on-abi-stability&gt;Effect) on ABI stability
> > 
> > None.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#effect-on-api-resilience&gt;Effect) on API resilience
> > 
> > This proposal adds new methods to the public API of Sequence and conforming types.
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#alternatives-considered&gt;Alternatives) considered
> > 
> > It is to be noted that lexicographicallyPrecedes(\_:by:) and elementsEqual(\_:by:) are essentially the same method, since both perform a lexicographical comparison using a custom predicate. However, there is not a good unifying name. (lexicographicallyCompares(to:by:) reads poorly.) Moreover, the predicate supplied is intended to have very different semantics, and maintaining two distinct methods may be a superior fit with the typical user's mental model of the intended behavior and may also be clearer to readers of the code. Therefore, this proposal does not seek to unify the two methods; instead, elementsEqual(\_:by:) will be renamed lexicographicallyEquals(\_:by:) as detailed above.
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [October 15, 2017, 3:44am UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/17 "2017-10-15T03:44:43Z")

</div>

> I think that “match” is a word to avoid for this, as this doesn’t have  
> anything to do with pattern matching, fuzzy matching, etc., while “equals”  
> is precisely the concept we’re using.
> 
> What about the name “sequentiallyEquals”? Highlight the fact that we’re  
> talking about sequential ordering, i.e. whatever order the sequence  
> provides, as opposed to first doing some lexicographical ordering of  
> elements themselves.
> 
> var a: Set\<Int\> = [3, 1, 2]  
> a.sequentiallyEquals([1,2,3]) // result depends on application of equality  
> in a (potentially-arbitrary) sequential ordering
> 
> Whereas I could see the following being more confusing:
> 
> var a: Set\<Int\> = [3, 1, 2]  
> a.lexicographicallyEquals([1,2,3]) // result depends on application of  
> equality, but what meaning does “lexicographically” convey?
> 
> It’s not immediately clear to someone new to the API that  
> “lexicographically” speaks to the nature of the sequence’s  
> (potentially-arbitrary) order, irrespective of element. It could give the  
> false impression that it speaks to some nature of the elements themselves,  
> in this case Ints, which have an obvious lexicographical ordering. I don’t  
> know how frequent that misconception would be in practice, but it does  
> cause me to do a double-take in this contrived example.

I'm entirely puzzled that apparently large numbers of people believe  
lexicographical comparison, a term with a very specific mathematical  
definition and no colloquial use, to mean what it does not. I'd like to  
avoid inventing Swift-specific new terms for this particular concept which  
is not at all unique to Swift. The other plausible terms I can see with  
some other use might be "elementwise equals" or "entrywise equals" or  
"coordinatewise equals."

> **···**
>
> On Sat, Oct 14, 2017 at 8:11 PM, Michael Ilseman \<milseman@apple.com\> wrote:
> 
> > On Oct 14, 2017, at 1:04 PM, Benjamin G via swift-evolution \< \> swift-evolution@swift.org\> wrote:
> > 
> > To answer more precisely this request (which remains valid no matter the  
> > protocol hierarchy). I propose
> > 
> > "matchesSequence" ( or simply "matches" or "match", whatever is more  
> > coherent with the naming guidelines).
> > 
> > So  
> > var a: [Int] = [1,2,3]  
> > a.matchesSequence([1,2,3]) returns true.
> > 
> > I first thought that the verb "matching" was too heavily associated to  
> > regular expressions, but i think that it's the correct equivalent for  
> > something as general as a sequence.
> > 
> > On Fri, Oct 13, 2017 at 1:24 AM, Xiaodi Wu via swift-evolution \< \> swift-evolution@swift.org\> wrote:
> > 
> > > Rename Sequence.elementsEqual
> > > 
> > > &nbsp;&nbsp;&nbsp;- Proposal: SE-NNNN  
> > > &nbsp;&nbsp;&nbsp;\<[https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt](https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt);  
> > > &nbsp;&nbsp;&nbsp;- Authors: Xiaodi Wu \<[https://github.com/xwu&gt](https://github.com/xwu&gt);  
> > > &nbsp;&nbsp;&nbsp;- Review Manager: TBD  
> > > &nbsp;&nbsp;&nbsp;- Status: \*Awaiting review\*
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#introduction&gt);  
> > > Introduction
> > > 
> > > The current behavior of Sequence.elementsEqual 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  
> > > Sequence.lexicographicallyEquals.  
> > > \<[https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#motivation&gt](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#motivation&gt);  
> > > Motivation
> > > 
> > > As outlined by Ole Begemann  
> > > \<[https://twitter.com/olebegemann/status/916291785185529857&gt;](https://twitter.com/olebegemann/status/916291785185529857&gt;), use of  
> > > Sequence.elementsEqual(\_:) can lead to surprising results if the  
> > > sequences compared are unordered:
> > > 
> > > var set1: Set\<Int\> = Set(1...5)var set2: Set\<Int\> = Set((1...5).reversed())
> > > 
> > > set1 == set2 // trueset1.elementsEqual(set2) // false
> > > 
> > > This result does reflect the \*intended and documented\* behavior of the  
> > > elementsEqual(\_:) method, which performs a \*lexicographical\* elementwise  
> > > comparison. That is, the method first compares set1.first to set2.first,  
> > > then (if the two elements compare equal) compares the next element stored  
> > > internally in set1 to the next element stored internally in set2, and so  
> > > on.
> > > 
> > > In almost all circumstances where a set is compared to another set, or a  
> > > dictionary is compared to another dictionary, users should use ==  
> > > instead of elementsEqual(\_:).
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#proposed-solution&gt;Proposed)  
> > > solution
> > > 
> > > The proposed solution is the result of an iterative process of reasoning,  
> > > presented here:
> > > 
> > > The first and most obvious solution is to remove the elementsEqual(\_:)  
> > > method altogether in favor of ==. This prevents its misuse. However,  
> > > because elementsEqual(\_:) is a generic method on Sequence, we can use it  
> > > to compare an instance of UnsafeBufferPointer\<Int\> to an instance of  
> > > [Int]. This is a useful and non-redundant feature which would be  
> > > eliminated if the method is removed altogether.
> > > 
> > > A second solution \<[https://github.com/apple/swift/pull/12318&gt](https://github.com/apple/swift/pull/12318&gt); is to  
> > > create overloads that forbid the use of the elementsEqual(\_:) method  
> > > specifically in non-generic code. This would prevent misuse in non-generic  
> > > code; however, it would also forbid legitimate mixed-type comparisons in  
> > > non-generic code while failing to prevent misuse in generic code. The  
> > > solution also creates a difference in the behavior of generic and  
> > > non-generic code calling the same method, which is potentially confusing,  
> > > without solving the problem completely.
> > > 
> > > A third solution is to dramatically overhaul the protocol hierarchy for  
> > > Swift sequences and collections so that unordered collections no longer  
> > > have members such as first and elementsEqual(\_:). However, this would be  
> > > a colossal and source-breaking undertaking, and it is unlikely to be  
> > > satisfactory in addressing all the axes of differences among sequence and  
> > > collection types:
> > > 
> > > &nbsp;&nbsp;&nbsp;- Finite versus infinite  
> > > &nbsp;&nbsp;&nbsp;- Single-pass versus multi-pass  
> > > &nbsp;&nbsp;&nbsp;- Ordered versus unordered  
> > > &nbsp;&nbsp;&nbsp;- Lazy versus eager  
> > > &nbsp;&nbsp;&nbsp;- Forward/bidirectional/random-access
> > > 
> > > A fourth solution is proposed here. It is predicated on the following  
> > > observation:
> > > 
> > > \*Another method similar to elementsEqual(\_:) already exists on Sequence  
> > > named lexicographicallyPrecedes(\_:). Like first, elementsEqual(\_:),  
> > > drop(while:), and others, it relies on the internal order of elements in a  
> > > manner that is not completely suitable for an unordered collection.  
> > > However, like first and unlike elementsEqual(\_:), this fact is called out  
> > > in the name of the method; unsurprisingly, like first and unlike  
> > > elementsEqual(\_:), there is no evidence that lexicographicallyPrecedes(\_:)  
> > > has been a pitfall for users.\*
> > > 
> > > This observation suggests that a major reason for confusion over  
> > > elementsEqual(\_:) stems from its name. So, \*it is proposed that  
> > > elementsEqual(\_:) should be renamed to lexicographicallyEquals(\_:)\*. The  
> > > function will remain somewhat of a poor fit for unordered collections, but  
> > > no more so than many other methods that cannot trivially be removed from  
> > > the API of unordered collections (as discussed above). The key is that,  
> > > with such a renaming, the behavior of this method will no longer be  
> > > confusing.
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#detailed-design&gt;Detailed)  
> > > design
> > > 
> > > extension Sequence where Element : Equatable {  
> > > &nbsp;&nbsp;@available(\*, deprecated, message: "Use '==' if possible to compare two sequences of the same type, or use 'lexicographicallyEquals' to compare two ordered sequences.")  
> > > &nbsp;&nbsp;public func elementsEqual\<Other : Sequence\>(  
> > > &nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
> > > &nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;return lexicographicallyEquals(other)  
> > > &nbsp;&nbsp;}
> > > 
> > > &nbsp;&nbsp;public func lexicographicallyEquals\<Other : Sequence\>(  
> > > &nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
> > > &nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;// The body of this method is unchanged. var iter1 = self.makeIterator()  
> > > &nbsp;&nbsp;&nbsp;&nbsp;var iter2 = other.makeIterator()  
> > > &nbsp;&nbsp;&nbsp;&nbsp;while true {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch (iter1.next(), iter2.next()) {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case let (e1?, e2?):  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if e1 != e2 { return false }  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (\_?, nil), (nil, \_?):  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (nil, nil):  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > > &nbsp;&nbsp;&nbsp;&nbsp;}  
> > > &nbsp;&nbsp;}  
> > > }
> > > 
> > > A parallel change will be made with respect to elementsEqual(\_:by:);  
> > > that is, it will be deprecated in favor of lexicographicallyEquals(\_:by:)  
> > > .
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#source-compatibility&gt;Source)  
> > > compatibility
> > > 
> > > Existing code that uses elementsEqual will gain a deprecation warning.
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#effect-on-abi-stability&gt;Effect)  
> > > on ABI stability
> > > 
> > > None.
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#effect-on-api-resilience&gt;Effect)  
> > > on API resilience
> > > 
> > > This proposal adds new methods to the public API of Sequence and  
> > > conforming types.
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#alternatives-considered&gt;Alternatives)  
> > > considered
> > > 
> > > It is to be noted that lexicographicallyPrecedes(\_:by:) and  
> > > elementsEqual(\_:by:) are essentially the same method, since both perform  
> > > a lexicographical comparison using a custom predicate. However, there is  
> > > not a good unifying name. (lexicographicallyCompares(to:by:) reads  
> > > poorly.) Moreover, the predicate supplied is intended to have very  
> > > different semantics, and maintaining two distinct methods may be a superior  
> > > fit with the typical user's mental model of the intended behavior and may  
> > > also be clearer to readers of the code. Therefore, this proposal does not  
> > > seek to unify the two methods; instead, elementsEqual(\_:by:) will be  
> > > renamed lexicographicallyEquals(\_:by:) as detailed above.
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![masters3d](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@masters3d](https://forums.swift.org/u/masters3d)\
**Post date:** [October 16, 2017, 12:57am UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/18 "2017-10-16T00:57:38Z")

</div>

> I think that “match” is a word to avoid for this, as this doesn’t have anything to do with pattern matching, fuzzy matching, etc., while “equals” is precisely the concept we’re using.
> 
> What about the name “sequentiallyEquals”? Highlight the fact that we’re talking about sequential ordering, i.e. whatever order the sequence provides, as opposed to first doing some lexicographical ordering of elements themselves.
> 
> var a: Set\<Int\> = [3, 1, 2]  
> a.sequentiallyEquals([1,2,3]) // result depends on application of equality in a (potentially-arbitrary) sequential ordering

I really like this name.

It does make me think about .first which I now feel it should be .sequentiallyFirst :)

I ultimately think that these methods/properties do not make sense for unordered types so probably they should just be unavailable.

> **···**
>
> > On Oct 14, 2017, at 6:11 PM, Michael Ilseman via swift-evolution \<swift-evolution@swift.org\> wrote:
> 
> > Whereas I could see the following being more confusing:
> > 
> > var a: Set\<Int\> = [3, 1, 2]  
> > a.lexicographicallyEquals([1,2,3]) // result depends on application of equality, but what meaning does “lexicographically” convey?
> > 
> > It’s not immediately clear to someone new to the API that “lexicographically” speaks to the nature of the sequence’s (potentially-arbitrary) order, irrespective of element. It could give the false impression that it speaks to some nature of the elements themselves, in this case Ints, which have an obvious lexicographical ordering. I don’t know how frequent that misconception would be in practice, but it does cause me to do a double-take in this contrived example.
> > 
> > > On Oct 14, 2017, at 1:04 PM, Benjamin G via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> > > 
> > > To answer more precisely this request (which remains valid no matter the protocol hierarchy). I propose
> > > 
> > > "matchesSequence" ( or simply "matches" or "match", whatever is more coherent with the naming guidelines).
> > > 
> > > So  
> > > var a: [Int] = [1,2,3]  
> > > a.matchesSequence([1,2,3]) returns true.
> > > 
> > > I first thought that the verb "matching" was too heavily associated to regular expressions, but i think that it's the correct equivalent for something as general as a sequence.
> > > 
> > > On Fri, Oct 13, 2017 at 1:24 AM, Xiaodi Wu via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:  
> > > Rename Sequence.elementsEqual
> > > 
> > > Proposal: SE-NNNN \<[https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt](https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt);  
> > > Authors: Xiaodi Wu \<[https://github.com/xwu&gt](https://github.com/xwu&gt);  
> > > Review Manager: TBD  
> > > Status: Awaiting review  
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#introduction&gt;Introduction)
> > > 
> > > The current behavior of Sequence.elementsEqual 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 Sequence.lexicographicallyEquals.
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#motivation&gt;Motivation)
> > > 
> > > As outlined by Ole Begemann \<[https://twitter.com/olebegemann/status/916291785185529857&gt;](https://twitter.com/olebegemann/status/916291785185529857&gt;), use of Sequence.elementsEqual(\_:) can lead to surprising results if the sequences compared are unordered:
> > > 
> > > var set1: Set\<Int\> = Set(1...5)  
> > > var set2: Set\<Int\> = Set((1...5).reversed())
> > > 
> > > set1 == set2 // true  
> > > set1.elementsEqual(set2) // false  
> > > This result does reflect the intended and documented behavior of the elementsEqual(\_:) method, which performs a lexicographical elementwise comparison. That is, the method first compares set1.first to set2.first, then (if the two elements compare equal) compares the next element stored internally in set1 to the next element stored internally in set2, and so on.
> > > 
> > > In almost all circumstances where a set is compared to another set, or a dictionary is compared to another dictionary, users should use == instead of elementsEqual(\_:).
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#proposed-solution&gt;Proposed) solution
> > > 
> > > The proposed solution is the result of an iterative process of reasoning, presented here:
> > > 
> > > The first and most obvious solution is to remove the elementsEqual(\_:) method altogether in favor of ==. This prevents its misuse. However, because elementsEqual(\_:) is a generic method on Sequence, we can use it to compare an instance of UnsafeBufferPointer\<Int\> to an instance of [Int]. This is a useful and non-redundant feature which would be eliminated if the method is removed altogether.
> > > 
> > > A second solution \<[https://github.com/apple/swift/pull/12318&gt](https://github.com/apple/swift/pull/12318&gt); is to create overloads that forbid the use of the elementsEqual(\_:) method specifically in non-generic code. This would prevent misuse in non-generic code; however, it would also forbid legitimate mixed-type comparisons in non-generic code while failing to prevent misuse in generic code. The solution also creates a difference in the behavior of generic and non-generic code calling the same method, which is potentially confusing, without solving the problem completely.
> > > 
> > > A third solution is to dramatically overhaul the protocol hierarchy for Swift sequences and collections so that unordered collections no longer have members such as first and elementsEqual(\_:). However, this would be a colossal and source-breaking undertaking, and it is unlikely to be satisfactory in addressing all the axes of differences among sequence and collection types:
> > > 
> > > Finite versus infinite  
> > > Single-pass versus multi-pass  
> > > Ordered versus unordered  
> > > Lazy versus eager  
> > > Forward/bidirectional/random-access  
> > > A fourth solution is proposed here. It is predicated on the following observation:
> > > 
> > > Another method similar to elementsEqual(\_:) already exists on Sequence named lexicographicallyPrecedes(\_:). Like first, elementsEqual(\_:), drop(while:), and others, it relies on the internal order of elements in a manner that is not completely suitable for an unordered collection. However, like first and unlike elementsEqual(\_:), this fact is called out in the name of the method; unsurprisingly, like first and unlike elementsEqual(\_:), there is no evidence that lexicographicallyPrecedes(\_:) has been a pitfall for users.
> > > 
> > > This observation suggests that a major reason for confusion over elementsEqual(\_:) stems from its name. So, it is proposed that elementsEqual(\_:) should be renamed to lexicographicallyEquals(\_:). The function will remain somewhat of a poor fit for unordered collections, but no more so than many other methods that cannot trivially be removed from the API of unordered collections (as discussed above). The key is that, with such a renaming, the behavior of this method will no longer be confusing.
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#detailed-design&gt;Detailed) design
> > > 
> > > extension Sequence where Element : Equatable {  
> > > &nbsp;&nbsp;@available(\*, deprecated, message: "Use '==' if possible to compare two sequences of the same type, or use 'lexicographicallyEquals' to compare two ordered sequences.")  
> > > &nbsp;&nbsp;public func elementsEqual\<Other : Sequence\>(  
> > > &nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
> > > &nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;return lexicographicallyEquals(other)  
> > > &nbsp;&nbsp;}  
> > > &nbsp;&nbsp;  
> > > &nbsp;&nbsp;public func lexicographicallyEquals\<Other : Sequence\>(  
> > > &nbsp;&nbsp;&nbsp;&nbsp;\_ other: Other  
> > > &nbsp;&nbsp;) -\> Bool where Other.Element == Element {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;// The body of this method is unchanged.  
> > > &nbsp;&nbsp;&nbsp;&nbsp;var iter1 = self.makeIterator()  
> > > &nbsp;&nbsp;&nbsp;&nbsp;var iter2 = other.makeIterator()  
> > > &nbsp;&nbsp;&nbsp;&nbsp;while true {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch (iter1.next(), iter2.next()) {  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case let (e1?, e2?):  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if e1 != e2 { return false }  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (\_?, nil), (nil, \_?):  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case (nil, nil):  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true  
> > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > > &nbsp;&nbsp;&nbsp;&nbsp;}  
> > > &nbsp;&nbsp;}  
> > > }  
> > > A parallel change will be made with respect to elementsEqual(\_:by:); that is, it will be deprecated in favor of lexicographicallyEquals(\_:by:).
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#source-compatibility&gt;Source) compatibility
> > > 
> > > Existing code that uses elementsEqual will gain a deprecation warning.
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#effect-on-abi-stability&gt;Effect) on ABI stability
> > > 
> > > None.
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#effect-on-api-resilience&gt;Effect) on API resilience
> > > 
> > > This proposal adds new methods to the public API of Sequence and conforming types.
> > > 
> > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#alternatives-considered&gt;Alternatives) considered
> > > 
> > > It is to be noted that lexicographicallyPrecedes(\_:by:) and elementsEqual(\_:by:) are essentially the same method, since both perform a lexicographical comparison using a custom predicate. However, there is not a good unifying name. (lexicographicallyCompares(to:by:) reads poorly.) Moreover, the predicate supplied is intended to have very different semantics, and maintaining two distinct methods may be a superior fit with the typical user's mental model of the intended behavior and may also be clearer to readers of the code. Therefore, this proposal does not seek to unify the two methods; instead, elementsEqual(\_:by:) will be renamed lexicographicallyEquals(\_:by:) as detailed above.
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![knatt](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/knatt/32/22335_2.png) [@knatt](https://forums.swift.org/u/knatt)\
**Post date:** [October 13, 2017, 5:12pm UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/19 "2017-10-13T17:12:27Z")

</div>

> > –∞
> > 
> > 1. I strongly object to the proposed name. It doesn't make it more clear to me what the method does, and is misleading at best. Among other issues, "lexicographical" is defined as alphabet order, and (1) this method applies to objects that are not Strings, and (2) this method's behavior isn't any more well-defined for Strings, so that name is even more of a lie than the original.
> 
> FWIW, in the context of String, "lexicographical ordering” does not imply human-written-language-alphabetical order at all, as there’s no universal alphabetical ordering for human language. I.e., such a concrete notion for Strings does not exist, not even theoretically. “Lexicographical” derives its meaning from the mathematical usage[1] which uses that term as well as “alphabet” without being restricted to human-written-language, in which it means some total ordering over a finite set.
> 
> [1] [Lexicographic order - Wikipedia](https://en.wikipedia.org/wiki/Lexicographical_order)

I see, apologies for the mistake.  
Regardless of the specific type of ordering, lexicographicallyEquals says to me that the objects should be sorted into lexicographical order and compared. Precisely the opposite of the proposal.

> **···**
>
> > On Oct 13, 2017, at 10:01 AM, Michael Ilseman \<milseman@apple.com\> wrote:
> > 
> > > On Oct 12, 2017, at 9:57 PM, Kevin Nattinger via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> 
> > > 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'll outline the real issue in case someone has an idea for fixing it.
> > > 
> > > The root of the problem is that Set conforms to Sequence, but Sequence doesn't require a well-defined order. Since Set doesn'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't have well-defined or necessarily consistent results.
> > > 
> > > 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.
> > > 
> > > \* 7/12 by my count, ignoring `_*` funcs but including the `var`
> > > 
> > > 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.
> > > 
> > > I think those should be/should have been two separate protocols:
> > > 
> > > public protocol Iterable {  
> > > &nbsp;&nbsp;associatedtype Iterator: IteratorProtocol  
> > > &nbsp;&nbsp;func map\<T\>(...) -\> [T] // Iterable where .Iterator.Element == T  
> > > &nbsp;&nbsp;func filter(...) -\> [Iterator.Element] // Iterable where .Iterator.Element == Self.Iterator.Element  
> > > &nbsp;&nbsp;func forEach(...)  
> > > &nbsp;&nbsp;func makeIterator() -\> Iterator  
> > > &nbsp;&nbsp;var underestimatedCount: Int { get }  
> > > }
> > > 
> > > public protocol Sequence: Iterable { // Maybe OrderedSequence just to make the well-defined-order requirement explicit  
> > > &nbsp;&nbsp;associatedtype SubSequence  
> > > &nbsp;&nbsp;func dropFirst(...) -\> SubSequence // Sequence where .Iterator.Element == Self.Iterator.Element  
> > > &nbsp;&nbsp;func dropLast(...) -\> SubSequence // " "  
> > > &nbsp;&nbsp;func drop(while...) -\> SubSequence // " "  
> > > &nbsp;&nbsp;func prefix(...) -\> SubSequence // " "  
> > > &nbsp;&nbsp;func prefix(while...) -\> SubSequence // " "  
> > > &nbsp;&nbsp;func suffix(...) -\> SubSequence // " "  
> > > &nbsp;&nbsp;func split(...where...) -\> [SubSequence] // Iterable where .Iterator.Element == (Sequence where .Iterator.Element == Self.Iterator.Element)  
> > > }
> > > 
> > > (The comments, of course, would be more sensible types once the ideas can actually be expressed in Swift)
> > > 
> > > 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.
> > > 
> > > Now, the practical matter. If this were Swift 1-\>2 or 2-\>3, I doubt there would be a significant issue with actually making this change. Unfortunately, we're well beyond that and making a change this deep is an enormous deal. So I see two ways forward.
> > > 
> > > 1. We could go ahead and make this separation. Although it'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.
> > > 
> > > 2. We could try and think of a way to make the distinction between ordered and unordered "sequences" in a less-breaking manner. Unfortunately, I don't have a good suggestion for this, but if anyone has ideas, I'm all ears. Or eyes, as the case may be.
> > > 
> > > > On Oct 12, 2017, at 4:24 PM, Xiaodi Wu via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> > > > 
> > > > Rename Sequence.elementsEqual
> > > > 
> > > > Proposal: SE-NNNN \<[https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt](https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt);  
> > > > Authors: Xiaodi Wu \<[https://github.com/xwu&gt](https://github.com/xwu&gt);  
> > > > Review Manager: TBD  
> > > > Status: Awaiting review  
> > > > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#introduction&gt;Introduction)
> > > > 
> > > > The current behavior of Sequence.elementsEqual 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 Sequence.lexicographicallyEquals.
> > > > 
> > > > [...]
> > > 
> > > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > > swift-evolution mailing list  
> > > swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>  
> > > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![xwu](https://avatars.discourse-cdn.com/v4/letter/x/b487fb/32.png) [@xwu](https://forums.swift.org/u/xwu)\
**Post date:** [October 13, 2017, 12:17pm UTC](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821/20 "2017-10-13T12:17:32Z")

</div>

“Lexicographical comparison” is a pretty standard term, and easy to Google.  
We didn’t make it up for Swift :)

Since Swift names this protocol Sequence, something named  
“Sequence.sequenceEqual” cannot distinguish this method from ==.

> **···**
>
> On Fri, Oct 13, 2017 at 01:28 Adam Kemp \<adam.kemp@apple.com\> wrote:
> 
> > I agree that the proposed name is a poor choice. 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.
> > 
> > --  
> > Adam Kemp
> > 
> > On Oct 12, 2017, at 9:57 PM, Kevin Nattinger via swift-evolution \< \> swift-evolution@swift.org\> wrote:
> > 
> > –∞
> > 
> > 1. I strongly object to the proposed name. It doesn't make it more clear  
> > to me what the method does, and is misleading at best. Among other issues,  
> > "lexicographical" is defined as alphabet order, and (1) this method applies  
> > to objects that are not Strings, and (2) this method's behavior isn't any  
> > more well-defined for Strings, so that name is even more of a lie than the  
> > original.
> > 
> > 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'll outline the real issue  
> > in case someone has an idea for fixing it.
> > 
> > \*The root of the problem is that Set conforms to Sequence, but Sequence  
> > doesn't require a well-defined order.\* Since Set doesn'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't have  
> > well-defined or necessarily consistent results.
> > 
> > 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.
> > 
> > \* 7/12 by my count, ignoring `_*` funcs but including the `var`
> > 
> > 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.
> > 
> > I think those should be/should have been two separate protocols:
> > 
> > public protocol Iterable {  
> > &nbsp;&nbsp;associatedtype Iterator: IteratorProtocol  
> > &nbsp;&nbsp;func map\<T\>(...) -\> [T] // Iterable where .Iterator.Element == T  
> > &nbsp;&nbsp;func filter(...) -\> [Iterator.Element] // Iterable where  
> > .Iterator.Element == Self.Iterator.Element  
> > &nbsp;&nbsp;func forEach(...)  
> > &nbsp;&nbsp;func makeIterator() -\> Iterator  
> > &nbsp;&nbsp;var underestimatedCount: Int { get }  
> > }
> > 
> > public protocol Sequence: Iterable { // Maybe OrderedSequence just to  
> > make the well-defined-order requirement explicit  
> > &nbsp;&nbsp;associatedtype SubSequence  
> > &nbsp;&nbsp;func dropFirst(...) -\> SubSequence // Sequence where  
> > .Iterator.Element == Self.Iterator.Element  
> > &nbsp;&nbsp;func dropLast(...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func drop(while...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func prefix(...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func prefix(while...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func suffix(...) -\> SubSequence // " "  
> > &nbsp;&nbsp;func split(...where...) -\> [SubSequence] // Iterable where  
> > .Iterator.Element == (Sequence where .Iterator.Element ==  
> > Self.Iterator.Element)  
> > }
> > 
> > (The comments, of course, would be more sensible types once the ideas can  
> > actually be expressed in Swift)
> > 
> > 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.
> > 
> > Now, the practical matter. If this were Swift 1-\>2 or 2-\>3, I doubt there  
> > would be a significant issue with actually making this change.  
> > Unfortunately, we're well beyond that and making a change this  
> > deep is an enormous deal. So I see two ways forward.
> > 
> > 1. We could go ahead and make this separation. Although it'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.
> > 
> > 2. We could try and think of a way to make the distinction between ordered  
> > and unordered "sequences" in a less-breaking manner. Unfortunately, I don't  
> > have a good suggestion for this, but if anyone has ideas, I'm all ears. Or  
> > eyes, as the case may be.
> > 
> > On Oct 12, 2017, at 4:24 PM, Xiaodi Wu via swift-evolution \< \> swift-evolution@swift.org\> wrote:
> > 
> > Rename Sequence.elementsEqual
> > 
> > &nbsp;&nbsp;&nbsp;- Proposal: SE-NNNN  
> > &nbsp;&nbsp;&nbsp;\<[https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt](https://gist.github.com/xwu/NNNN-rename-elements-equal.md&gt);  
> > &nbsp;&nbsp;&nbsp;- Authors: Xiaodi Wu \<[https://github.com/xwu&gt](https://github.com/xwu&gt);  
> > &nbsp;&nbsp;&nbsp;- Review Manager: TBD  
> > &nbsp;&nbsp;&nbsp;- Status: \*Awaiting review\*
> > 
> > \<[Rename Sequence.elementsEqual · GitHub](https://gist.github.com/xwu/1f0ef4e18a7f321f22ca65a2f56772f6#introduction&gt);  
> > Introduction
> > 
> > The current behavior of Sequence.elementsEqual 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  
> > Sequence.lexicographicallyEquals.  
> > [...]
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_
> > 
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

[Next page](https://forums.swift.org/t/draft-rename-sequence-elementsequal/6821.md?page=2)
