no it really isn’t… just look at the so answer I linked why that isn’t the case.
- I’m not sure what SO did, but apparently my browser doesn’t scroll to the linked answer (it merely flashes red when I scroll near it, which is confusing).
- I see something about sequence points, but this seems irrelevant to Rust? ISTM order of evaluation is well-defined in rust.
Why though? First, that question and answer is about C++, not Rust. Second, it states that
!= is xor without a sequence point (?). Third, Rust doesn’t really have sequence points, the evaluation rules are formulated differently. Fourth, the reason it seems to consider sequence points is the use of xor with side-effecting expressions, which are also not idiomatic Rust to say the least, and most of them can’t even be used as booleans, given that e.g. assignments have type
(). (Of course you could come up with a
bool-returning effectful function, but at that point, why would you even write such code…?)
This thread reminds me that there is something quite unclear about the whole operator story in Rust and I think this should be clarified before adding new operators, in particular overloadable ones. It seems there exist two incompatible views of what an operator trait is:
- As for every other trait in Rust it represents a well defined (set of) semantic operation(s) that just happen to be aliasable with predefined sigils.
- It is just a workaround to allow the use of sigils when dealing with specific types. However it enforces no strong semantic on what the operations mean. Basically library authors are more or less free to equip their types with operators they like (but with of course the same readability and least-surprise constrains as with any other method name).
I suspect many of us consider the answer is obviously 1. because most of the time this interpretation works well. But there are already obvious defects:
- Trait Div does not correspond to the same operation when applied to integers or floating points. I don’t think one would express anything useful by specifying a bound
where T : Div.
- Add for string concatenation have little in common with the addition of numbers. Note that the monoid argument does not hold given the current state of the standard library. First because as already noticed multiple times here, a multiplicative operator should be prefered for the operator of any non-commutative monoid. Second because LinkedList and any sequential collections (and more generally any free monoid) should also have a concatenation operator if we want consistency.
- BitAnd and BitOr are implemented for sets, which could be considered consistent with bitwise operations on integers if we are considering them to be the operations of a boolean algebra (or more generally a lattice). But in that case the naming is rather inappropriate and should be something like conjunction/disjunction or join/meet.
- The ? operator is still sometime refered to as the question mark operator. I know there is now a dedicated thread to rename it but this still shows there is a temptation in Rust to think of operators in term of sigils rather than in term of operations.
Note that if we stick to intepretation 1. it should not be impossible to have several operator traits using the same sigils if their semantic are considered too divergent. That may not be desirable most of the time but it is not different from homonymous methods in distinct traits.
Bikeshed: A consise verb for the `?` operator