+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 { >> @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>( >> _ other: Other >> ) -> Bool where Other.Element == Element { >> return lexicographicallyEquals(other) >> } >> >> public func lexicographicallyEquals<Other : Sequence>( >> _ other: Other >> ) -> Bool where Other.Element == Element { >> // The body of this method is unchanged. >> var iter1 = self.makeIterator() >> var iter2 = other.makeIterator() >> while true { >> switch (iter1.next(), iter2.next()) { >> case let (e1?, e2?): >> if e1 != e2 { return false } >> case (_?, nil), (nil, _?): >> return false >> case (nil, nil): >> return true >> } >> } >> } >> } >> 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 >> > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution