[swift-evolution] [pitch] Comparison Reform

Xiaodi Wu xiaodi.wu at gmail.com
Sun Apr 16 11:15:09 CDT 2017


On Sun, Apr 16, 2017 at 1:13 AM, Dave Abrahams via swift-evolution <
swift-evolution at swift.org> wrote:

> <snip>
>
>> > I have an incipient idea. It begins with:
> >> >
> >> > enum ComparisonResult {
> >> >   case orderedAscending, orderedSame, orderedDescending, unordered
> >> > }
> >> >
> >> > I am sure there is something I am missing which makes this design a
> >> > horrible idea, but I'm interested in hearing them.
> >>
> >> It's not a horrible idea, but to be fair it's not really a design yet,
> >> either.  You haven't said anything about what it's supposed to mean, how
> >> it is supposed to be used, how people write, use, and compose generic
> >> algorithms with it, how it deals with floating point, etc.
> >>
> >
> > I've evolved my thinking based on the discussion. Let's see:
> >
> > ```
> > public enum ComparisonResult : Equatable {
> >   case orderedAscending, equivalent, orderedDescending, unordered
> >   // I have renamed one case, in the hopes of emphasizing that two values
> >   // that compare `equivalent` are not merely ordered the same, but
> should
> >   // satisfy the three conditions of an equivalence relation.
> > }
> > // I will have to leave the question of how to bridge from Obj-C
> > // NSComparisonResult up to more capable hands.
> >
> > public protocol Comparable : Equatable {
> >   func compared(to other: Self) -> ComparisonResult
> > }
> > // This will have to be modified as necessarily to support compiler magic
> > // necessary for source-compatibility with Swift 3
> >
> > extension Comparable {
> >   public static func == (lhs: Self, rhs: Self) -> Bool {
> >     let comparison = lhs.compared(to: rhs)
> >     precondition(comparison != .unordered)
> >     return comparison == .equivalent
> >   }
> >
> >   public static func < (lhs: Self, rhs: Self) -> Bool {
> >     let comparison = lhs.compared(to: rhs)
> >     precondition(comparison != .unordered)
> >     return comparison == .orderedAscending
> >   }
> >   // etc.
> >
> >   // Something I thought I'd never want to see, but on reflection not
> > terrible:
> >   public static func &== (lhs: Self, rhs: Self) -> Bool {
> >     return lhs.compared(to: rhs) == .equivalent
> >   }
> >
> >   public static func &< (lhs: Self, rhs: Self) -> Bool {
> >     return lhs.compared(to: rhs) == .orderedAscending
> >   }
> >   // etc.
> > }
> >
> > extension FloatingPoint : Comparable {
> >   public func compared(to other: Self) -> ComparisonResult {
> >     if isNaN || other.isNaN { return .unordered }
> >     if isLess(than: other) { return .orderedAscending }
> >     if other.isLess(than: self) { return .orderedDescending }
> >
> >     // On reconsideration, probably actually least surprising if +0.0 ==
> > -0.0
> >     // no matter what. It does not matter that division can give
> different
> >     // results for two equivalent values, only that the three rules of an
> >     // equivalence relation will hold, and it does.
> >     //
> >     // If a user is really savvy to the sign of zero, there is
> > FloatingPoint.sign,
> >     // which is necessary in any case for working with FP operations that
> >     // distinguish between +0 and -0. I can't think of a generic
> algorithm
> > over
> >     // all Comparable types that could make use of the distinction
> between
> > +0
> >     // and -0.
> >     return .equivalent
> >   }
> > }
> > ```
> >
> > In this design, `==`, `<`, etc. correspond to IEEE "signaling" operators,
> > while `&==`, `&<`, etc. correspond to C-style operators, which IEEE calls
> > "quiet" and actually notates using "?==", "?<", etc.
>
> It's interesting, but what's missing here is a description of the user
> model.  How do users program with this design?  What should my
> expectations be w.r.t. generic algorithms like sort() and floating point
> numbers, particularly NaN?  If, as I suspect, sorting a collection
> containing NaN is going to trap (unless the collection has only one
> element?), why is that the right behavior?


I've spent some time fleshing out this idea:
https://gist.github.com/xwu/e864ffdf343160a8a26839388f677768
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170416/3e05615b/attachment.html>


More information about the swift-evolution mailing list