Here's one use case your proposal doesn't cover:
Subtracting two points returns a vector, which either has the same internal
representation as a point or uses point as its internal representation, and
thus, despite the return type of the subtraction operation being different from
`Self`, it's still eligible for the implicit move-optimization.
For example, assuming a `Sub` definition that moves `self`:
struct Point {
coordinates: Vec<int>
}
struct Vector {
end_point: Point
}
impl Sub<Point, Vector> for Point {
fn sub(self, rhs: &Point) -> Vector {
for (left, right) in
self.coordinates.mut_iter().zip(rhs.coordinates.iter()) {
*left -= *right;
}
Vector { end_point: self }
}
}
On 2014-06-17, at 11:04, Jan Klesnil <[email protected]> wrote:
> Hi,
>
> Maybe we should look at the problem from other perspective? Currently the x
> += y expression is sugar for x = x + y. Can we flip it over and make x = x +
> y expression sugar for x = { let tmp = x; tmp += y }? What to do for non-Copy
> types then?
>
> It can be fixed by having traits for both + and += operators with default
> implementation of Add for Copy types.
>
> trait Add<RHS> {
> fn add(&mut self, &rhs : RHS);
> }
>
> trait BinaryAdd<RHS, RES> {
> fn add(&self, &rhs : RHS) -> RES;
> }
>
> impl<RHS, T : Copy + Add<RHS>> BinaryAdd<RHS, T> for T {
> fn add(&self, &rhs : RHS) -> T {
> let mut tmp = self;
> tmp += rhs;
> tmp
> }
> }
>
> For any addable type you either implement Add and Copy, or Add and BinaryAdd
> if the type is too expensive to be implicitly copyable, or just the BinaryAdd
> if the result's type is different from Self.
>
> Then the rustc may be allowed to use Add instead of BinaryAdd for temporary
> values and for += expressions:
> let a = a + b; => a += b;
> let c = get_new_foo() + b; => let c=get_new_foo(); c+=b;
> c += a;
>
> It will be user's responsibility to provide compatible implementations for
> Add and BinaryAdd (results, side-effects, etc.).
>
> JK
>
> On 16.6.2014 16:32, Sebastian Gesemann wrote:
>> The following message got sent to Patrick instead to the list by mistake.
>> Sorry, Patrick!
>>
>> ---------- Forwarded message ----------
>> From: [email protected]
>> Date: Mon, Jun 16, 2014 at 4:29 PM
>> Subject: Re: [rust-dev] &self/&mut self in traits considered harmful(?)
>> To: Patrick Walton <[email protected]>
>>
>>
>> On Sat, Jun 14, 2014 at 2:46 AM, Patrick Walton wrote:
>>> I have filed RFC #118 for this:
>>> https://github.com/rust-lang/rfcs/pull/118
>>>
>>> Patrick
>> Bold move. But I'm not convinced that this is a good idea. I may be
>> missing something, but forcing a move as opposed to forcing an
>> immutable reference seems just as bad as an approach. Also, I'm not
>> sure why you mention C++ rvalue references there. References in C++
>> are not objects/values like C++ Pointers or References in Rust. They
>> are auto-borrowing and auto-deref'ing non-values, so to speak. These
>> different kinds of L- and Rvalue references combined with overloading
>> is what makes C++ enable move semantics.
>>
>> I think one aspect of the issue is Rust's Trait system itself. It
>> tries to kill two birds with one stone: (1) Having "Interfaces" with
>> runtime dispatching where Traits are used as dynamically-sized types
>> and (2) as type bound for generics. Initially, I found this to be a
>> very cool Rust feature. But now, I'm not so sure about that anymore.
>> Back in 2009 when "concepts" were considered for C++ standardization,
>> I spent much time on understanding the intricacies of that C++ topic.
>> This initial "concepts" design also tried to define some type
>> requirements in terms of function signatures. But this actually
>> interacted somewhat badly with rvalue references (among other things)
>> and I think this is one of the reasons why "concepts lite" (a new and
>> simplified incarnation of the concepts design, expected to augment
>> C++1y standard in form of a technical report) replaced the function
>> signatures with "usage patterns". As a user of some well-behaved type,
>> I don't really care about what kind of optimizations it offers for +
>> or * and how they work. I'm just glad that I can "use" the "pattern"
>> x*y where x and y refer to instances of some type. Whether the
>> implementer of that type distinguishes between lvalues and rvalues via
>> overloading or not is kind of an implementation detail that does not
>> affect how the type is being used syntactically. So, I expect "C++
>> concepts lite" to be able to specify type requirements in terms of
>> "usage patters" in a way that it allows "models" of these "concepts"
>> to satisfy the requirements in a number of ways (with move
>> optimizations being optional but possible).
>>
>> Another thing I'm not 100% comfortable with (yet?) is the funky way
>> references are used in Rust in combination with auto-borrowing (for
>> operators and self at least) and auto-deref'ing while at the same
>> time, they are used as "values" (like C++ pointers as opposed to C++
>> references). I've trouble putting this into words. But it feels to me
>> like the lines are blurred which could cause some trouble or bad
>> surprizes.
>>
>> 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? I could write
>>
>> impl Add<&T,T> for &T {...}
>>
>> but it seems to me that this requires explicit borrowing in the user code à
>> la
>>
>> let x: T = ...;
>> let y: T = ...;
>> let c = &x + &y;
>>
>> Or is this also handled via implicit borrowing for operators (making
>> operators a special case)?
>>
>> Still, I find it very weird to impl Add for &T instead of T and have
>> this asymmetry between &T and T for operands and return value.
>>
>> Can you shed some more light on your RFC? Maybe including examples? A
>> discussion about the implications? How it would affect Trait-lookup,
>> implicit borrowing etc? What did you mean by "The AutorefArgs stuff in
>> typeck will be removed; all overloaded operators will typecheck as
>> though they were DontAutorefArgs."? Many thanks in advance!
>>
>> Cheers
>> sg
>> _______________________________________________
>> Rust-dev mailing list
>> [email protected]
>> https://mail.mozilla.org/listinfo/rust-dev
>
> _______________________________________________
> Rust-dev mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/rust-dev
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev