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 1
s 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:
-
LessThan
for<
-
LessEq
for<=
-
GreaterThan
for>
-
GreaterEq
for>=
-
Equals
for==
-
NotEquals
for!=
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?