Comparable and FloatingPoint types

I’ve been thinking about this for some time today. It seems clear that the current capabilities of Swift provide no (fully) satisfying solution to address the inconsistency between the < operator on FloatingPoint types and the semantics that Equatable and Comparable expect.

Protocol conformances as they exist today generate confusion when a type can conform to a protocol in multiple ways and there isn’t an obvious choice. Moreover they don’t allow to express alternative conformances at all. The same argument came up a few weeks ago in Make Numeric Refine a new AdditiveArithmetic Protocol:

What if Swift had a notion of “named protocol conformances” that could be used to satisfy generic requirements only if referenced explicitly at the point of usage? Current protocol conformances, on the other hand, would become the “default” conformances to a protocol and would still be able to satisfy requirements implicitly.

FloatingPoint types would then be able to offer multiple protocol conformances to Comparable. For example, they could offer a total order that would fully respect Comparable semantics, a partial order that traps on NaNs, an order based on IEEE comparison, … Perhaps the first one would be the only one that really makes sense, but this model would still allow the others to exists. Importantly, users could add them retroactively with an extension if the standard library didn’t provide them.

I argue that in such a model FloatingPoint could offer no default conformance to Comparable at all. If you wanted to sort an array of Doubles, you would be forced to specify which order should be used and there would be no possible ambiguity with the outcome. This feels a bit drastic, but with the right ergonomics it should not increase complexity significantly while definitely improving clarity.

Is this a model that could reasonably be introduced in a future version of Swift? If yes, is there something in the language today that would prevent it from being implemented once the ABI is declared stable?

(This is the first time that I try to participate on Swift Evolution, so I could be missing something really obvious. I hope my contribution can be useful nonetheless)

2 Likes