[swift-evolution] [Review] Tuple comparison operators (was: Add a Lazy flatMap for Sequences of Optionals)

Kevin Ballard kevin at sb.org
Tue Dec 22 15:03:23 CST 2015


On Tue, Dec 22, 2015, at 10:39 AM, Guillaume Lessard via swift-evolution wrote:
> I wholeheartedly support the Equatable (==) portion of this proposal.
> I’m quite negative about the Comparable portion; it doesn’t really make sense.
> 
> The justification for making Tuples comparable pretty much consists of hand-waving.
> Why should (0,3,4) be smaller than (0,5,0)? Beats me.
> Why would it be the other way around? Also beats me.

You're proposing that there isn't a clear reason for it to behave the way it is, but you haven't given any justification for this claim. I say there is in fact a clear reason, and that reason is that lexicographical order is a pretty common assumption.

> I can vaguely see the utility of Comparable when I squint, but the actual behaviour would require extensive documentation with caveats about it not really making any sense. To overload an operator with a clear meaning with a behaviour with a wishy-washy definition is a bad idea.

It makes sense in any situation where lexicographical comparisons is appropriate, which I would wager covers most of the times where tuple comparisons in general make sense. Not only that, but providing an easy way to invoke lexicographical comparison using tuples allows people to invoke this behavior easily on arbitrary data when they need it.

It was mentioned in the old proposal thread that providing an equality operator on tuples makes it easy to implement equality on structs by just comparing tuples constructed from the struct fields. Comparison operators have the same benefit. For example:

struct Version: Comparable {
    let major: Int
    let minor: Int
    let patch: Int
}

func ==(lhs: Version, rhs: Version) -> Bool {
    return (lhs.major, lhs.minor, lhs.patch) == (rhs.major, rhs.minor, rhs.patch)
}

func <(lhs: Version, rhs: Version) -> Bool {
    return (lhs.major, lhs.minor, lhs.patch) < (rhs.major, rhs.minor, rhs.patch)
}

> * Is the problem being addressed significant enough to warrant a change to Swift?
> 
> Yes for Equatable.
> No for Comparable.
> 
> 
> * Does this proposal fit well with the feel and direction of Swift?
> 
> Yes for Equatable.
> No for Comparable.
> 
> 
> * If you have you used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
> 
> I have used Mathematics during an extensive education in Physics and Engineering, at the end of which I escaped with a Ph.D. from a major institution.
> 
> Making arbitrary Tuples Equatable when possible makes sense.
> Making them Comparable absolutely does not.
> 
> Comparability is domain-specific. The standard library cannot know what an arbitrary Tuple means.

The standard library cannot know this for equality either. But you still think that makes sense. There's plenty of ways to construct tuples where the meaning of equality of the whole is different than the meaning of equality of parts. And if this distinction is important to capture, you're free to define a struct instead of using a tuple, as you can then provide whatever specific notion of equality (or comparability) you want.

I guess the overall question is, given that lexicographical ordering is a very common ordering, what harm is there in providing a lexicographical ordering operation on tuples? If it doesn't make sense for the tuple in question, then just don't try and compare it. Heck, we provide a comparison operator on strings even though the particular comparison it implements isn't always what you want (for example, it's case-sensitive and you may want case-insensitive comparison) but nobody is arguing that strings shouldn't be comparable.

-Kevin Ballard

> * How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
> 
> I drew upon my experience. While I feel it’s on solid footing, I would hesitate to call it an in-depth study.
> 
> 
> Finally, I would like to note that I would support a free-standing function with a clear name that does the same thing as the proposed overloads of the comparison operator.
> 
> Sincerely,
> Guillaume Lessard
> 
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution


More information about the swift-evolution mailing list