@kornel I'm not sure which argument you are trying to make here.
Being able to design your own DSLs allows you to design both good and bad DSLs. In Rust, <<
is already a purely syntactic operator, so implementing C++ <iostream>
in Rust with the same API is already possible.
You argue that such a DSL is bad, and therefore, <
should not be allowed to be syntactically overloaded. But since this is a problem that we already have, I argue that allowing to overload <
does not only make the language more consistent, but it also makes this problem better, since it allows designing better DSLs.
If Rust wants to enable more syntax sugar, I suggest allowing custom infix functions/operators, so that users can define their own new operators with their own semantics, without creating ambiguity around existing operators.
a vecmul! b
ora v* b
ora \* b
ora โ b
, etc.
Since we are talking about translating the mathematical vec < vec
operator to Rust, how would you add this particular operator under this proposal, and how is that better than using <
for it along the multiple axes that make a DSL good (actually representing the language it is supposed to represent, in this case, math; being intuitive, discoverable, etc.) ?
This would work terribly with
#[derive(PartialOrd)]
and generic impls.
Can you explain why? AFAICT it would work perfectly with derive(PartialOrd)
and generic impls.
For me the big issue with all such syntax-extension proposals is their justification: How much harder does the proposal make it to learn and use Rust for the average user, vs. how much benefit does it provide in actual code use?
I maintain a widely used crate and being able to use <
for comparing SIMD vectors is one of the most requested features by users.
If this weren't the case and these operators use (
partial_
)cmp
directly, this proposal could hold more weight. As it is, since these operators already have an overload path, arguing for adding another one is going to take a lot of doing.
Since the proposal actually proposes an implementable solution, whose implementation is actually extremely simple, and fully backward compatible with PartialOrd
/PartialEq
, I suppose the proposal misses something that you consider obvious. Could you elaborate on what that is? EDIT: maybe by "a lot of doing" you are not referring to implementation issues as I understood at first, but to process issues like achieving consensus on an RFC?
Rust so far has generally taken a position of "don't overload operators to do anything other than the obvious meaning that has been drilled into your head since elementary".
Can you mention for which operators this is the case? AFAICT, all Rust operators that come with an associated Target
type (that's all of them except for the relational operators) are purely syntactical and allow you to do something non-obvious and this is exploited by many crates, including the standard library. So if anything, the position that Rust has taken is completely the opposite to the one you claim.
Note that the OP example also requires
bool - bool : {integer}
, which I don't think would ever happen.
This is incorrect. The OP example requires a < b
to have a customizable output type, which is very different from this claim that the output type must be bool
. In particular, for SIMD vectors, (a < b)
does not return a vector of bool, but a "vector mask", which is a vector of the same type as the ones being compared. Adding an implementation of Sub
for {vector mask} - {vector mask}: {vector}
is already possible with the current Sub
trait design, so this wouldn't be an issue. That is, if you think that bool - bool: {integer}
would be bad, then this is a problem that we already have, because it is already possible to write a Rust library with a struct Bool(bool);
type such that Bool - Bool: {integer}
. The only thing this RFC allow is syntactically overloading relational operators, such that if that library has a struct Int(i32);
it can implement <
for it such that Int < Int: Bool
. The only problematic part here is that, if you do this, there is no way to make Int
be PartialOrd
, but fixing that is an orthogonal problem.