Something else. As @xwu mentions, this is the payoff that never materialized due to structural concerns in the type system. I'm arguing (at the limit) for something like this:
protocol LessThanable {
// This is not spelled "func <" and not injected into the global scope!!
static func lessThan(a : Self, b : Self) -> Bool
}
// There can be only one, and it shall be (T,T)->Bool (*)
func < <T : LessThanable>(a : T, b: T) -> Bool {
return T.lessThan(a: a, b: b)
}
// not actually allowed :( - you know what I mean.
extension BinaryInteger : LessThanable {
static func lessThan(a : Self, b : Self) -> Bool {
...
}
}
Similarly you do that with FP types, and all of the other concrete implementations of the types. The point is that the compiler does name lookup of <
and finds exactly one match. This means that the exponential search of various possibilities has to consider exactly one operator instead of N when it sees "42 < x".
Now, we have a complication here: for comparisons (but not normal arithmetic) we went down the path of allowing mixed operands to comparisons (which was perhaps a bad idea in hindsight). This means you need a second mixed operator like:
func < <T, S>(a: T, b: S) -> Bool {
...
}
It is unfortunate that we have to support 2 implementations (meaning we get a disjunction in the constraint solver) but one disjunction with 2 possibilities should be FAR FAR Better than a disjunction with N possibilities - each of which need to be exponentially searched. Also, this issue doesn't affect + or * or other non comparison operations.
-Chris