[rust-dev] Fwd: &self/&mut self in traits considered harmful(?)

SiegeLord slabode at aim.com
Thu Jun 19 04:59:19 PDT 2014


On 06/19/2014 07:08 AM, Sebastian Gesemann wrote:
> No, it's more like
>
>    a + x * (b + x * (c + x * d)))

It can't be that and be efficient as it is right now (returning a clone 
for each binop). I am not willing to trade efficiency for sugar, 
especially not when trade is this bad (in fact that's the entire point 
of this thread). In my matrix library through the use of lazy evaluation 
I can make my code run as fast as a manual loop implementation would. 
This would not be the case here.

I will note that you could very well implement a by-value self operator 
overload trait

> The difference is that the short operator-based expression *works*
> right now whereas forcing a "moving self type" on to people makes this
> expression not compile for types that are not Copy. So, given the two
> options, I actually prefer the way things are right now.

It's inefficient, so it doesn't 'work'.

> I think, to convince people (either way) a deeper analysis is needed.

I don't think merely changing the type of self/arg to be by move is the 
only solution, or the best solution. It does seem to be the case that 
different operators benefit from reusing temporaries differently, but 
it's clear that *some* operators definitely do (e.g. thing/scalar 
operators, addition/subtraction, element-wise matrix-operators) and the 
current operator overloading traits prevent that optimization without 
the use of RefCell or lazy evaluation. Both of those have non-trivial 
semantic costs. In the case of operators that do benefit from reusing 
temporaries, doing so via moving seems very natural and relatively clean.

Regardless, bignum and linear-algebra are prime candidates for operator 
overloading, but the way it is done now by most implementations is just 
unsatisfactory. Maybe bignums in std::num and all the linear algebra 
libraries could be converted to use a lazy evaluation, thus avoiding 
this issue of changing the operator overload traits. Alternatively, 
maybe the whole operator-overloading idea-via traits is broken anyway 
since operators do have such different semantics for different types (in 
particular, efficient semantics of operators differ from built-in 
numeric types and complicated library numeric types). Maybe adding 
attributes to methods (e.g. #[operator_add] fn my_add(self, whatever) {} 
) is more flexible since it is becoming clear that generic numeric code 
(generic to bignums and normal integers and matrices) might not be a 
possibility.

I should note that it is already an impossibility in many cases (I 
guarantee that my lazy matrix library won't fulfill the type bounds of 
any function due to how its return types differ from the argument types).

-SL


More information about the Rust-dev mailing list