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

Sebastian Gesemann s.gesemann at gmail.com
Mon Jun 16 16:03:15 PDT 2014


Am 17.06.2014 00:17, schrieb Cameron Zwarich:
> On Jun 16, 2014, at 3:03 PM, Cameron Zwarich <zwarich at mozilla.com> wrote:
> 
>> On Jun 16, 2014, at 2:24 PM, Patrick Walton <pcwalton at mozilla.com> wrote:
>>
>>> On 6/16/14 1:04 PM, Sebastian Gesemann wrote:
>>>> Am 16.06.2014 19:36, schrieb Patrick Walton:
>>>>> On 6/16/14 7:32 AM, Sebastian Gesemann wrote:
>>>>>> Assuming this RFC is accepted: How would I have to implement Add for a
>>>>>> custom type T where moving doesn't make much sense and I'd rather use
>>>>>> immutable references to bind the operands?
>>>>>
>>>>> You don't implement Add for those types.
>>>>
>>>> As far as I'm concerned that's anything but a satisfactory answer. I
>>>> really don't see the point of your RFC. If anything, it seems to make
>>>> things worse from my perspective. That's why I asked you for some
>>>> clarifications. Of course, you don't owe me anything. And I hope you
>>>> don't take this personally.
>>>
>>> I don't see much of a use case for `Add` without move semantics. Does anyone have any?
>>>
>>> Strings and vectors, perhaps, but I would argue that having to call `.clone()` on the LHS or RHS (as appropriate) is an improvement, because cloning strings and vectors can be very expensive.
>>
>> This applies to Mul rather than Add, but if you are multiplying matrices then you want the destination to not alias either of the sources for vectorization purposes, so passing by reference is preferred.
> 
> I stated the right case, but the wrong reason. It’s not for vectorization, it’s because it’s not easy to reuse the storage of a matrix while multiplying into it.

Good example! I think even with scalar multiplication/division for
bignum it's hard to do the calculation in-place of one operand. In those
cases this RFC would cost us a couple of unnecessary clones (assuming
one wants to keep using the variables as opposed to having them moved from).

Suppose I want to evaluate a polynomial over "BigRationals" using
Horner's method:

  a + x * (b + x * (c + x * d))

What I DON'T want to type is

  a + x.clone() * (b + x.clone() * (c + x.clone() * d))

and I hope that I'm not the only one who would dislike having to write
this. So, this would not only be ugly to write down, it would also add
unnecessary clones in case Mul impl for that type is not able to
calculate the result in-place but allocates new heap storage for the
result anyways.

I'm leaning towards keeping things as they are and telling people who
want to benefit from move semantics to provide additional functions like

  x.inplace_add(y)

with

  fn inplace_add(self, rhs: &SomeBigType) -> SomeBigType {...}

or something like this.


- esgeh



More information about the Rust-dev mailing list