Motivation: In general, this helps building better DSLs for many applications, e.g., array processing, machine learning, numerics, SIMD, parallelism, etc.
For example, consider this APL example from 1962 that implements signum (return 0 if 0, -1 if negative, and +1 if positive) on arrays:
(x>0)-(x<0)
(that's all the code)
Here, x > 0 tests whether each element of an array is 0, returning an array containing 1s where this is true, and 0 where this is false`.
In C++, this signum function can be implemented in exactly this way, e.g., using Eigen or many other libraries for manipulating arrays.
Now try to implement signum for arrays in Rust using your favourite Rust library, e.g., ndarray, packed_simd, etc. Using packed_simd, x<0 would be x.lt(0), since SIMD vectors cannot implement PartialOrd.
Reference-level explanation: Add the following traits to libcore core::ops that get used to lower the relational operators:
-
LessThanfor< -
LessEqfor<= -
GreaterThanfor> -
GreaterEqfor>= -
Equalsfor== -
NotEqualsfor!=
These traits all follow the same pattern, exemplarily shown here for LessThan:
// mod core::ops
trait LessThan<Rhs = Self> {
type Target;
fn less_than(&self, rhs: &Rhs) -> Self::Target;
}
impl<T: ?Sized + PartialOrd<Rhs>, Rhs: ?Sized> LessThan<Rhs> for T {
type Target = bool;
fn less_than(&self, other: &Rhs) -> bool {
PartialOrd::lt(self, other)
}
}
There is an implementation of this proposal by @CAD97 here: https://github.com/CAD97/rust/commits/cmp
Unresolved questions:
- Would this change be technically possible? I think so, but not sure.
- If so,
- what would the drawbacks of making this change be?
- are there any other motivating examples I should be aware of?