Sorting a collection will not use `&lt;` as the default predicate.<br><br>In the Gist, I&#39;ve outlined a design for `[Double].sorted()` which would exhibit identical behavior to what is proposed in this thread, but the design would be different under the hood. In brief, the &quot;go-to&quot; overload for sorting a collection of comparable elements would be:<br><br>sorted(_ sortOrder: SortOrder = .ascending, by comparison: (Iterator.Element, Iterator.Element) -&gt; Comparison? = `&lt;=&gt;`) -&gt; [Iterator.Element]<br><br>which would notionally use the following for the predicate known today as `areInIncreasingOrder`:<br><br>{<br>  switch sortOrder {<br>  case .ascending:<br>    return comparison($0, $1) == .some(.less) || comparison($1, $1) == .none<br>  case .descending:<br>    return comparison($1, $0) == .some(.less) || comparison($0, $0) == .none<br>  }<br>}<br><br>(We would add an enum `SortOrder` distinct from `Comparison` for reasons spelled out in the Gist--not really germane to your question, though. And, although the compiler may or may not do it today, there ought to be no reason why it cannot optimize away checks for `comparison(a, b) == .none` if values of the concrete type never compare unordered--i.e. if the function passed as the second argument to `sorted` returns `Comparison` instead of `Comparison?`.)<br><br>(The `Comparison` instead of `Comparison?` thing, incidentally, is for me the crux of my alternative design. I&#39;m quite proud of it. It allows us to recover most (all?) the benefits of knowing at compile time which types are &quot;partially&quot; comparable and which are not, but *without* having a distinct protocol named PartiallyComparable. That is, the one protocol `Comparable` would require a comparison method that returns an instance of type `Comparison?`. Conforming types that never compare unordered can fulfill that requirement with a method that returns `Comparison` (non-optional). Both the compiler and readers can gain something meaningful from that. Meanwhile, we avoid the disaster of generic algorithms having two different protocols to choose from and potentially not supporting floating point.)<br><br>With this design, each generic function would decide how to handle unordered comparisons. I believe this to be superior because ordering NaN greater than all other values produces an acceptable result for `sort` but a rather unintuitive one for `max`, and there is no reason why we should have to tolerate that.<br><br>Using `sort(by: &lt;)` explicitly with a collection of elements that may compare unordered will give a compiler warning, as `&lt;` would not satisfy the semantic requirements for a sort predicate. Nothing will forbid the user from passing an arbitrary function as a predicate, though, just as we do not stop someone from writing `sort(by: ==)` today. The warning about using `&lt;` will be silenced by writing `sort { $0 &lt; $1 }`.<br><br>For perfect migration of existing code, `sort(by: &lt;)` can be migrated to the proposed spelling `sort(by: &amp;&lt;)` and retain Swift 3 behavior in every way, including the same wonky results with NaN. Otherwise, `sort(.ascending)` and `sort(.descending)` would be the preferred way to write the same thing, with more sensible results when sorting NaN.<br><br><div class="gmail_quote"><div dir="ltr">On Mon, Apr 17, 2017 at 11:40 Dave Abrahams via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
on Sun Apr 16 2017, Xiaodi Wu &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br>
<br>
&gt; On Sun, Apr 16, 2017 at 1:13 AM, Dave Abrahams via swift-evolution &lt;<br>
&gt; <a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br>
&gt;<br>
&gt;&gt; &lt;snip&gt;<br>
&gt;&gt;<br>
&gt;&gt;&gt; &gt; I have an incipient idea. It begins with:<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt; enum ComparisonResult {<br>
&gt;&gt; &gt;&gt; &gt;   case orderedAscending, orderedSame, orderedDescending, unordered<br>
&gt;&gt; &gt;&gt; &gt; }<br>
&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt; &gt; I am sure there is something I am missing which makes this design a<br>
&gt;&gt; &gt;&gt; &gt; horrible idea, but I&#39;m interested in hearing them.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; It&#39;s not a horrible idea, but to be fair it&#39;s not really a design yet,<br>
&gt;&gt; &gt;&gt; either.  You haven&#39;t said anything about what it&#39;s supposed to mean, how<br>
&gt;&gt; &gt;&gt; it is supposed to be used, how people write, use, and compose generic<br>
&gt;&gt; &gt;&gt; algorithms with it, how it deals with floating point, etc.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; I&#39;ve evolved my thinking based on the discussion. Let&#39;s see:<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; ```<br>
&gt;&gt; &gt; public enum ComparisonResult : Equatable {<br>
&gt;&gt; &gt;   case orderedAscending, equivalent, orderedDescending, unordered<br>
&gt;&gt; &gt;   // I have renamed one case, in the hopes of emphasizing that two values<br>
&gt;&gt; &gt;   // that compare `equivalent` are not merely ordered the same, but<br>
&gt;&gt; should<br>
&gt;&gt; &gt;   // satisfy the three conditions of an equivalence relation.<br>
&gt;&gt; &gt; }<br>
&gt;&gt; &gt; // I will have to leave the question of how to bridge from Obj-C<br>
&gt;&gt; &gt; // NSComparisonResult up to more capable hands.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; public protocol Comparable : Equatable {<br>
&gt;&gt; &gt;   func compared(to other: Self) -&gt; ComparisonResult<br>
&gt;&gt; &gt; }<br>
&gt;&gt; &gt; // This will have to be modified as necessarily to support compiler magic<br>
&gt;&gt; &gt; // necessary for source-compatibility with Swift 3<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; extension Comparable {<br>
&gt;&gt; &gt;   public static func == (lhs: Self, rhs: Self) -&gt; Bool {<br>
&gt;&gt; &gt;     let comparison = lhs.compared(to: rhs)<br>
&gt;&gt; &gt;     precondition(comparison != .unordered)<br>
&gt;&gt; &gt;     return comparison == .equivalent<br>
&gt;&gt; &gt;   }<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;   public static func &lt; (lhs: Self, rhs: Self) -&gt; Bool {<br>
&gt;&gt; &gt;     let comparison = lhs.compared(to: rhs)<br>
&gt;&gt; &gt;     precondition(comparison != .unordered)<br>
&gt;&gt; &gt;     return comparison == .orderedAscending<br>
&gt;&gt; &gt;   }<br>
&gt;&gt; &gt;   // etc.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;   // Something I thought I&#39;d never want to see, but on reflection not<br>
&gt;&gt; &gt; terrible:<br>
&gt;&gt; &gt;   public static func &amp;== (lhs: Self, rhs: Self) -&gt; Bool {<br>
&gt;&gt; &gt;     return lhs.compared(to: rhs) == .equivalent<br>
&gt;&gt; &gt;   }<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;   public static func &amp;&lt; (lhs: Self, rhs: Self) -&gt; Bool {<br>
&gt;&gt; &gt;     return lhs.compared(to: rhs) == .orderedAscending<br>
&gt;&gt; &gt;   }<br>
&gt;&gt; &gt;   // etc.<br>
&gt;&gt; &gt; }<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; extension FloatingPoint : Comparable {<br>
&gt;&gt; &gt;   public func compared(to other: Self) -&gt; ComparisonResult {<br>
&gt;&gt; &gt;     if isNaN || other.isNaN { return .unordered }<br>
&gt;&gt; &gt;     if isLess(than: other) { return .orderedAscending }<br>
&gt;&gt; &gt;     if other.isLess(than: self) { return .orderedDescending }<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;     // On reconsideration, probably actually least surprising if +0.0 ==<br>
&gt;&gt; &gt; -0.0<br>
&gt;&gt; &gt;     // no matter what. It does not matter that division can give<br>
&gt;&gt; different<br>
&gt;&gt; &gt;     // results for two equivalent values, only that the three rules of an<br>
&gt;&gt; &gt;     // equivalence relation will hold, and it does.<br>
&gt;&gt; &gt;     //<br>
&gt;&gt; &gt;     // If a user is really savvy to the sign of zero, there is<br>
&gt;&gt; &gt; FloatingPoint.sign,<br>
&gt;&gt; &gt;     // which is necessary in any case for working with FP operations that<br>
&gt;&gt; &gt;     // distinguish between +0 and -0. I can&#39;t think of a generic<br>
&gt;&gt; algorithm<br>
&gt;&gt; &gt; over<br>
&gt;&gt; &gt;     // all Comparable types that could make use of the distinction<br>
&gt;&gt; between<br>
&gt;&gt; &gt; +0<br>
&gt;&gt; &gt;     // and -0.<br>
&gt;&gt; &gt;     return .equivalent<br>
&gt;&gt; &gt;   }<br>
&gt;&gt; &gt; }<br>
&gt;&gt; &gt; ```<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; In this design, `==`, `&lt;`, etc. correspond to IEEE &quot;signaling&quot; operators,<br>
&gt;&gt; &gt; while `&amp;==`, `&amp;&lt;`, etc. correspond to C-style operators, which IEEE calls<br>
&gt;&gt; &gt; &quot;quiet&quot; and actually notates using &quot;?==&quot;, &quot;?&lt;&quot;, etc.<br>
&gt;&gt;<br>
&gt;&gt; It&#39;s interesting, but what&#39;s missing here is a description of the user<br>
&gt;&gt; model.  How do users program with this design?  What should my<br>
&gt;&gt; expectations be w.r.t. generic algorithms like sort() and floating point<br>
&gt;&gt; numbers, particularly NaN?  If, as I suspect, sorting a collection<br>
&gt;&gt; containing NaN is going to trap (unless the collection has only one<br>
&gt;&gt; element?), why is that the right behavior?<br>
&gt;<br>
&gt; I&#39;ve spent some time fleshing out this idea:<br>
&gt; <a href="https://gist.github.com/xwu/e864ffdf343160a8a26839388f677768" rel="noreferrer" target="_blank">https://gist.github.com/xwu/e864ffdf343160a8a26839388f677768</a><br>
<br>
More interesting still, but you still failed to answer the final<br>
question above.<br>
<br>
--<br>
-Dave<br>
<br>
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote></div>