-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Description
It is well known that f32 and f64 are not totally orderable by default, and thus does not implement TotalOrd and TotalEq. However it is less known that we rarely need the total ordering in reality, and the standard library has only two cases requiring the total ordering (sorting and TreeMap). #12434 and #12435 are based on this observation, but we can think in the other direction: we can provide totally ordered wrappers for partially ordered types.
The suggested wrappers, TotallyOrderedF32 and TotallyOrderedF64 will be tuple (newtype) structs for f32 and f64. (Yes, I know this name doesn't look good, it's intentional.) They have the following constraints: (TOF for any of two types)
x < y and x == x and y == y implies TOF(x).cmp(&TOF(y)) == Less
x > y and x == x and y == y implies TOF(x).cmp(&TOF(y)) == Greater
x == y and x == x and y == y implies TOF(x).cmp(&TOF(y)) == Equal
x != y or y != y implies TOF(x).cmp(&TOF(y)) is arbitrary (but a function of x/y)
The actual implementation would be similar to IEEE 754-2008 totalOrder except that TOF(-0).cmp(&TOF(+0)) == Equal, otherwise we would break the constraints as -0 == +0. Combined with Deref (#7141, which would have to be implemented eventually) I no longer see the separation of Ord/Eq and TotalOrd/Eq is necessary. Usability-wise, the compiler can suggest TotallyOrderedF{32,64} on the failure to expand #[deriving(TotalOrd)] (and others) for f32 and f64.
This RFC only concerns about f32 and f64 since they are commonly encountered non-totally-ordered types, but if we want to pursue this further, we can alternatively provide a TotalOrder generic wrapper that massages Ord implementors to aforementioned constraints.