Re: [rust-dev] self/mut self in traits considered harmful(?)
On Jun 16, 2014, at 3:19 PM, Patrick Walton pcwal...@mozilla.com wrote: On 6/16/14 3:17 PM, Cameron Zwarich wrote: 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. Wouldn't most matrices be implicitly copyable (and thus optimized--or at least optimizable--into by-ref at the ABI level)? Sorry for the super-late reply, but if you reuse the same argument multiple times, you will have made multiple copies of it, right? A sufficiently optimizing compiler would probably be able to optimize it if everything is inlined. However, that also only applies to dense matrices. Sparse matrices are unlikely to be Copy. Cameron ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
Can you elaborate a bit more on why/how exactly did the earlier language design (implicitly clone by default if it's absolutely necessary and otherwise move, instead of move by default) result in much more cloning? Because intuitively it seems to me that if you try to use data that has been moved away, then it means that you didn't intend to move the data away in the first place, but to clone it. And vice versa. On 2014-06-12, at 21:15, Patrick Walton pcwal...@mozilla.com wrote: On 6/12/14 11:15 AM, Tommi wrote: On 2014-06-12, at 20:59, Corey Richardson co...@octayn.net mailto:co...@octayn.net wrote: Implicit cloning is a non-starter. Clones can be very expensive. Hiding that cost is undesirable and would require adding Clone to the language (it's currently a normal library feature). But I think it will be easy to make the error of writing the explicit .clone() in places where it's not needed. For example: fn fooT(value: T) {} let x = box 123; x.clone().foo(); x.clone().foo(); ...given that `x` is not used after those lines, the last call to .clone() is unnecessary. Whereas, if the task of cloning (implicitly) is assigned to the compiler, then the compiler can use static analysis to make sure such programming errors never occur. The example above would become something like: fn fooT(stable value: T) {} let x = box 123; x.foo(); // here `x` gets cloned here x.foo(); // here `x` doesn't get cloned because this is the last use of `x` We tried that in earlier versions of Rust. There were way too many clones. Patrick ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
On 2014-06-15, at 21:10, Isaac Dupree m...@isaac.cedarswampstudios.org wrote: On 6/12/14 11:15 AM, Tommi wrote: But I think it will be easy to make the error of writing the explicit .clone() in places where it's not needed. For example: [...] Would a compiler warning for unnecessary clones be feasible? useful? Would it have false positives -- situations where a clone would compile as a move but do the wrong thing? I would just ignore the first 12 of my posts on this thread. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
The manner in which the expression accomplishes this task is an implementation detail. You're welcome to draft a proposal if you think that you have an idea to make this possible. Though all of the solutions that I can envision require abandoning the idea of operators-as-traits and introducing a whole lot of magic in their place. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
On 2014-06-15, at 9:56, Benjamin Striegel ben.strie...@gmail.com wrote: You're welcome to draft a proposal if you think that you have an idea to make this possible. The idea of the `stable` keyword was designed specifically as a bandage on the current trait-system to allow a trait to say that: this function argument can be passed however you like as long as the caller of this function won't be able to see it modified. I introduced this idea on a long, previous post which began with: The problem: Chained calls to certain operators such as binary `*` and `+` may cause unnecessary memory allocations. [..] ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
I realized that, in my proposal, there's a potentially pretty confusing asymmetry of what `stable` means. In the trait definition: pub trait MulRHS, Result { fn mul(stable self, rhs: RHS) - Result; } ...the keyword `stable` means that however the type which implements this trait decides to pass `self` to `mul`, it must be guaranteed that the caller of `mul` won't be able to observe the variable passed in as `self` being modified by this call to `mul`. Also, a trait function that has at least one argument marked as `stable` wouldn't be allowed to have a provided (default) definition, because its signature doesn't say how that `stable` argument should be passed in. But on the actual implementation, like here: implT: Clone, RHS, Result MulRHS, Result for T { fn mul(stable self, rhs: RHS) - Result { ... } } ...the keyword `stable` means that the variable which the caller of `mul` passes in as the `self` argument will be implicitly cloned before it's passed in if it is necessary to do so in order to ensure that the caller of `mul` won't see that variable modified by `mul`. Static analysis will be used by the compiler to determine when this implicit cloning can be omitted (it may potentially be omitted due to the caller not observing the state of the passed in variable after the function call and (possibly) before the variable getting assigned a new value). Perhaps another keyword would be needed for this second meaning of `stable`, since it's completely different from the meaning of `stable` in trait functions. Maybe something like `cloned`. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
On 6/12/14 11:15 AM, Tommi wrote: But I think it will be easy to make the error of writing the explicit .clone() in places where it's not needed. For example: [...] Would a compiler warning for unnecessary clones be feasible? useful? Would it have false positives -- situations where a clone would compile as a move but do the wrong thing? -Isaac ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
I think that the deeper and larger language design issue here is that traits in some cases force you to impose on the trait-implementing type some implementation details that should remain hidden in the specification of the trait and should be left to the trait-implementing type to specify. The high level (of abstraction) description of an expression like: a * b ...is that that it should evaluate to the product of `a` and `b` without modifying neither `a` nor `b`. The manner in which the expression accomplishes this task is an implementation detail. If the expression above evaluates to a function call where `a` and `b` are passed as arguments, then the manner in which the two arguments are passed into such a function is an implementation detail, assuming there are multiple ways in which the arguments could be passed and the function call could still fulfill the high level requirements and guarantees of the expression. For example, POD `a` and `b` could be passed to such a product evaluating function in multiple ways, namely by value and by reference. If the definition of `Mul` trait specifies the exact manner in which the arguments must be passed to this product evaluating function, then the trait is revealing and imposing an implementation detail that should be left to the judgement of the type which implements such trait. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
The problem: Chained calls to certain operators such as binary `*` and `+` may cause unnecessary memory allocations. For example: struct Vector { coordinates: Vecint } impl Mulint, Vector for Vector { fn mul(self, rhs: int) - Vector { let mut new_coordinates = self.coordinates.clone(); for c in new_coordinates.mut_iter() { *c *= *rhs; } Vector { coordinates: new_coordinates } } } fn get_vector() - Vector { let v = Vector { coordinates: vec!(1, 2, 3) }; v * 2 * 5 } The last line of `get_vector` causes two new memory allocations. Preferably that line wouldn't allocate at all; it should take the guts out of `v` and multiply the coordinates in place. The goal: We want to be able to write the following function `calculate` and have it be guaranteed that `calculate` doesn't cause unnecessary memory allocations. fn calculateX, T: MulX, T + AddT, T(value: T, mult: X) - T { value * mult * mult + value } Insufficient first idea for a solution: Change the definition of `Mul` trait to: pub trait MulRHS, Result { fn mul(self, rhs: RHS) - Result; } And then, change the implementation of `Mul` for `Vector` to: impl Mulint, Vector for Vector { fn mul(self, rhs: int) - Vector { for c in self.coordinates.mut_iter() { *c *= *rhs; } self } } First of all, as a result of these changes, the `calculate` function wouldn't compile complaining about the last use of `value` that: error: use of moved value: `value`. This could be fixed by changing the definition of `calculate`, but this is not the main problem. But the real problem is that for some types, the binary `*` operator shouldn't move the `self` into the `mul` method. For example, when the return type of the `mul` method is different from the type of `self` (and both are heap allocated), then `mul` method is forced to allocate a new value which it returns, and it should take `self` by reference. My proposed solution: Add a new keyword `stable` to the language. Marking a function argument `stable` gives the guarantee to the caller of that function, that a variable passed in as that argument is logically unchanged after the function call ends. Then, change the definition of `Mul` trait to: pub trait MulRHS, Result { fn mul(stable self, rhs: RHS) - Result; } Note: any other syntax for marking `self` as `stable` would be illegal. One could implement `Mul` for any type by taking `self` by shared reference: implT, RHS, Result MulRHS, Result for T { fn mul(self, rhs: RHS) - Result { ... } } Or, one could implement `Mul` for any type that implements `Copy` by taking `self` by value: implT: Copy, RHS, Result MulRHS, Result for T { fn mul(self, rhs: RHS) - Result { ... } } Or, one could implement `Mul` for any type that implements `Clone` by taking `self` by stable value: implT: Clone, RHS, Result MulRHS, Result for T { fn mul(stable self, rhs: RHS) - Result { ... } } Taking an argument by stable value (as `self` above) means that any (clonable) variable passed in as that argument is implicitly cloned before it's passed in if the variable is potentially used after been passed in. For example: impl Mulint, Vector for Vector { fn mul(stable self, rhs: int) - Vector { for c in self.coordinates.mut_iter() { *c *= *rhs; } self } } fn testing() { let mut v = Vector { coordinates: vec!(1, 2, 3) }; v * 1; // Cloned due to not last use v * 1; // Not cloned due to last use before assignment v = Vector { coordinates: vec!(2, 4, 6) }; v * 1; // Cloned due to not last use v = v * 1; // Not cloned due to last use before assignment v * 1; // Not cloned due to last use } Open questions: What should happen for example with `Rc` types w.r.t. `stable`: implT, RHS, Result MulRHS, Result for RcT { fn mul(stable self, rhs: RHS) - Result { ... } } ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
On 2014-06-13, at 13:14, Tommi rusty.ga...@icloud.com wrote: pub trait MulRHS, Result { fn mul(stable self, rhs: RHS) - Result; } Note: any other syntax for marking `self` as `stable` would be illegal. Although, I could see this kind of syntax being allowed as well: pub trait MulRHS, Result { fn mul(stable lhs: Self, rhs: RHS) - Result; } ..and allowing similar syntax for an implementation like: implT: Clone, RHS, Result MulRHS, Result for T { fn mul(stable lhs: T, rhs: RHS) - Result { ... } } ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
I have filed RFC #118 for this: https://github.com/rust-lang/rfcs/pull/118 Patrick ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
On 2014-06-11, at 16:27, SiegeLord slab...@aim.com wrote: So, I think the situation is pretty bad. What can be done to fix it? I agree that this seems like a serious regression from C++. If it won't be fixed, I think I'll rather stick with C++. Better the devil you know... ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
On 6/12/14 1:02 AM, Tommi wrote: On 2014-06-11, at 16:27, SiegeLord slab...@aim.com mailto:slab...@aim.com wrote: So, I think the situation is pretty bad. What can be done to fix it? I agree that this seems like a serious regression from C++. If it won't be fixed, I think I'll rather stick with C++. Better the devil you know... This message is unhelpful. Patrick ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
On 6/11/14 6:27 AM, SiegeLord wrote: So, I think the situation is pretty bad. What can be done to fix it? Seems to me we can just make the overloaded operator traits take by-value self. Patrick ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
On 2014-06-12, at 19:08, Patrick Walton pcwal...@mozilla.com wrote: On 6/11/14 6:27 AM, SiegeLord wrote: So, I think the situation is pretty bad. What can be done to fix it? Seems to me we can just make the overloaded operator traits take by-value self. I definitely wouldn't want to see something like the following: pub trait GreaterByOneT { fn greater_by_one(self) - Self; } pub fn my_algorithmX, T: GreaterByOneX + AddT, T(value: T) - T { value.greater_by_one() + value.greater_by_one() // error: use of moved value: `value` } ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
You could just clone the value to get around that error. On June 12, 2014 10:03:40 AM PDT, Tommi rusty.ga...@icloud.com wrote: On 2014-06-12, at 19:08, Patrick Walton pcwal...@mozilla.com wrote: On 6/11/14 6:27 AM, SiegeLord wrote: So, I think the situation is pretty bad. What can be done to fix it? Seems to me we can just make the overloaded operator traits take by-value self. I definitely wouldn't want to see something like the following: pub trait GreaterByOneT { fn greater_by_one(self) - Self; } pub fn my_algorithmX, T: GreaterByOneX + AddT, T(value: T) - T { value.greater_by_one() + value.greater_by_one() // error: use of moved value: `value` } -- Sent from my Android phone with K-9 Mail. Please excuse my brevity.___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
Or bound by Copy. On Thu, Jun 12, 2014 at 10:17 AM, Patrick Walton pwal...@mozilla.com wrote: You could just clone the value to get around that error. On June 12, 2014 10:03:40 AM PDT, Tommi rusty.ga...@icloud.com wrote: On 2014-06-12, at 19:08, Patrick Walton pcwal...@mozilla.com wrote: On 6/11/14 6:27 AM, SiegeLord wrote: So, I think the situation is pretty bad. What can be done to fix it? Seems to me we can just make the overloaded operator traits take by-value self. I definitely wouldn't want to see something like the following: pub trait GreaterByOneT { fn greater_by_one(self) - Self; } pub fn my_algorithmX, T: GreaterByOneX + AddT, T(value: T) - T { value.greater_by_one() + value.greater_by_one() // error: use of moved value: `value` } -- Sent from my Android phone with K-9 Mail. Please excuse my brevity. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev -- http://octayn.net/ ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
I think a new keyword, something like `stable`, is needed for specifying that an argument passed to a trait function is guaranteed to be logically unchanged after the function call. For example: trait Foo { fn foo(stable self); } impl Foo for int { fn foo(self) {} // OK } impl Foo for uint { fn foo(self) {} // OK } impl Foo for Boxint { fn foo(stable self) {} // OK (implicitly clones self) } fn main() { let x: Boxint = box 42; x.foo(); // `x` is implicitly cloned x.foo(); // OK } ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
It's called Copy. `trait Foo: Copy { ... }`. On Thu, Jun 12, 2014 at 10:26 AM, Tommi rusty.ga...@icloud.com wrote: I think a new keyword, something like `stable`, is needed for specifying that an argument passed to a trait function is guaranteed to be logically unchanged after the function call. For example: trait Foo { fn foo(stable self); } impl Foo for int { fn foo(self) {} // OK } impl Foo for uint { fn foo(self) {} // OK } impl Foo for Boxint { fn foo(stable self) {} // OK (implicitly clones self) } fn main() { let x: Boxint = box 42; x.foo(); // `x` is implicitly cloned x.foo(); // OK } ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev -- http://octayn.net/ ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
`Copy` types aren't really relevant to a discussion about adding to Rust the C++ like optimization of moving rvalues (of non-Copy types) when they're passed to certain functions. On 2014-06-12, at 20:30, Corey Richardson co...@octayn.net wrote: It's called Copy. `trait Foo: Copy { ... }`. On Thu, Jun 12, 2014 at 10:26 AM, Tommi rusty.ga...@icloud.com wrote: I think a new keyword, something like `stable`, is needed for specifying that an argument passed to a trait function is guaranteed to be logically unchanged after the function call. For example: trait Foo { fn foo(stable self); } impl Foo for int { fn foo(self) {} // OK } impl Foo for uint { fn foo(self) {} // OK } impl Foo for Boxint { fn foo(stable self) {} // OK (implicitly clones self) } fn main() { let x: Boxint = box 42; x.foo(); // `x` is implicitly cloned x.foo(); // OK } ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev -- http://octayn.net/ ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
On 6/12/14 10:46 AM, Tommi wrote: `Copy` types aren't really relevant to a discussion about adding to Rust the C++ like optimization of moving rvalues (of non-Copy types) when they're passed to certain functions. There's nothing to add to Rust. Rust supports moves. Patrick ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
Implicit cloning is a non-starter. Clones can be very expensive. Hiding that cost is undesirable and would require adding Clone to the language (it's currently a normal library feature). On Thu, Jun 12, 2014 at 10:46 AM, Tommi rusty.ga...@icloud.com wrote: `Copy` types aren't really relevant to a discussion about adding to Rust the C++ like optimization of moving rvalues (of non-Copy types) when they're passed to certain functions. On 2014-06-12, at 20:30, Corey Richardson co...@octayn.net wrote: It's called Copy. `trait Foo: Copy { ... }`. On Thu, Jun 12, 2014 at 10:26 AM, Tommi rusty.ga...@icloud.com wrote: I think a new keyword, something like `stable`, is needed for specifying that an argument passed to a trait function is guaranteed to be logically unchanged after the function call. For example: trait Foo { fn foo(stable self); } impl Foo for int { fn foo(self) {} // OK } impl Foo for uint { fn foo(self) {} // OK } impl Foo for Boxint { fn foo(stable self) {} // OK (implicitly clones self) } fn main() { let x: Boxint = box 42; x.foo(); // `x` is implicitly cloned x.foo(); // OK } ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev -- http://octayn.net/ -- http://octayn.net/ ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
On 2014-06-12, at 20:51, Patrick Walton pcwal...@mozilla.com wrote: On 6/12/14 10:46 AM, Tommi wrote: `Copy` types aren't really relevant to a discussion about adding to Rust the C++ like optimization of moving rvalues (of non-Copy types) when they're passed to certain functions. There's nothing to add to Rust. Rust supports moves. You're right, I said it wrong (the last part, not the `Copy` being irrelevant part). There's no need to add to the language the ability to move (obviously it has that), but perhaps there's a need to add the ability to not move certain arguments by default, for convenience. I wouldn't want to see generic code littered with explicit .clone()'s all over the place. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
Sorry, Im a little new to Rust, but I'm,as many, now considering moving from c++ to Rust and the topic is really important for my tasks. Could you give an Rust example for the concern listed above? Thank you! On Jun 12, 2014 9:51 PM, Patrick Walton pcwal...@mozilla.com wrote: On 6/12/14 10:46 AM, Tommi wrote: `Copy` types aren't really relevant to a discussion about adding to Rust the C++ like optimization of moving rvalues (of non-Copy types) when they're passed to certain functions. There's nothing to add to Rust. Rust supports moves. Patrick ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
On 2014-06-12, at 20:59, Corey Richardson co...@octayn.net wrote: Implicit cloning is a non-starter. Clones can be very expensive. Hiding that cost is undesirable and would require adding Clone to the language (it's currently a normal library feature). But I think it will be easy to make the error of writing the explicit .clone() in places where it's not needed. For example: fn fooT(value: T) {} let x = box 123; x.clone().foo(); x.clone().foo(); ...given that `x` is not used after those lines, the last call to .clone() is unnecessary. Whereas, if the task of cloning (implicitly) is assigned to the compiler, then the compiler can use static analysis to make sure such programming errors never occur. The example above would become something like: fn fooT(stable value: T) {} let x = box 123; x.foo(); // here `x` gets cloned here x.foo(); // here `x` doesn't get cloned because this is the last use of `x` ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
On 6/12/14 11:15 AM, Tommi wrote: On 2014-06-12, at 20:59, Corey Richardson co...@octayn.net mailto:co...@octayn.net wrote: Implicit cloning is a non-starter. Clones can be very expensive. Hiding that cost is undesirable and would require adding Clone to the language (it's currently a normal library feature). But I think it will be easy to make the error of writing the explicit .clone() in places where it's not needed. For example: fn fooT(value: T) {} let x = box 123; x.clone().foo(); x.clone().foo(); ...given that `x` is not used after those lines, the last call to .clone() is unnecessary. Whereas, if the task of cloning (implicitly) is assigned to the compiler, then the compiler can use static analysis to make sure such programming errors never occur. The example above would become something like: fn fooT(stable value: T) {} let x = box 123; x.foo(); // here `x` gets cloned here x.foo(); // here `x` doesn't get cloned because this is the last use of `x` We tried that in earlier versions of Rust. There were way too many clones. Patrick ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
On 2014-06-12, at 21:15, Patrick Walton pcwal...@mozilla.com wrote: On 6/12/14 11:15 AM, Tommi wrote: On 2014-06-12, at 20:59, Corey Richardson co...@octayn.net mailto:co...@octayn.net wrote: Implicit cloning is a non-starter. Clones can be very expensive. Hiding that cost is undesirable and would require adding Clone to the language (it's currently a normal library feature). But I think it will be easy to make the error of writing the explicit .clone() in places where it's not needed. For example: fn fooT(value: T) {} let x = box 123; x.clone().foo(); x.clone().foo(); ...given that `x` is not used after those lines, the last call to .clone() is unnecessary. Whereas, if the task of cloning (implicitly) is assigned to the compiler, then the compiler can use static analysis to make sure such programming errors never occur. The example above would become something like: fn fooT(stable value: T) {} let x = box 123; x.foo(); // here `x` gets cloned here x.foo(); // here `x` doesn't get cloned because this is the last use of `x` We tried that in earlier versions of Rust. There were way too many clones. Oh, okay. But I bet you didn't have the `stable` keyword back then, and thus, all by-value arguments were implicitly `stable`, which I wouldn't suggest. Some functions clearly need to take a hold of the ownership of their argument and shouldn't need to guarantee that the variable passed in stays the same from the caller's point of view. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
For some reason I got really side-tracked here. The whole point of that `stable` keyword I proposed was not syntax sugar, but that it allows the implementor of such a trait to pass by reference when the operator shouldn't move the passed in argument(s). Like, when you multiply two matrices and the returned type is not the same size as neither of the arguments types, there's no point in modifying either of those arguments in place, but rather you need to allocate a new matrix. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
On Wed, Jun 11, 2014 at 3:27 PM, SiegeLord wrote: [...] Along the same lines, it is not immediately obvious to me how to extend this lazy evaluation idea to something like num::BigInt. So far, it seems like lazy evaluation will force dynamic dispatch in that case which is a big shame (i.e. you'd store the operations in one array, arguments in another and then play them back at the assignment time). I havn't tried something like expression templates in Rust yet. How did you come to the conclusion that it would require dynamic dispatch? ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
On 11/06/14 23:27, SiegeLord wrote: Aside from somewhat more complicated impl's, are there any downsides to never using anything but by value 'self' in traits? Currently trait objects do not support `self` methods (#10672), and, generally, the interactions with trait objects seem peculiar, e.g. if you've implemented Trait for Type, then you would want to be coercing a `Type` to a `Trait`, *not* a `(Type)` as is currently required. However, I don't think these concerns affect the operator overloading traits. https://github.com/mozilla/rust/issues/10672 Huon ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
On 06/11/2014 10:10 AM, Sebastian Gesemann wrote: On Wed, Jun 11, 2014 at 3:27 PM, SiegeLord wrote: [...] Along the same lines, it is not immediately obvious to me how to extend this lazy evaluation idea to something like num::BigInt. So far, it seems like lazy evaluation will force dynamic dispatch in that case which is a big shame (i.e. you'd store the operations in one array, arguments in another and then play them back at the assignment time). I havn't tried something like expression templates in Rust yet. How did you come to the conclusion that it would require dynamic dispatch? It's just the first idea I had with how this could work, but you're right, I can envision a way to do this without using dynamic dispatch. It'd look something like something like this: https://gist.github.com/SiegeLord/f1af81195df89ec04d10 . So, if nothing comes out of this discussion, at least you'd be able to do that. Note that the API is uglier, since you need to call 'eval' explicitly. Additionally, you need to manually borrow 'm' because you can't specify a lifetime of the self argument in mul (another problem with by-ref-self methods). -SL ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
If the `Mul` trait and similar were changed to take `self` by value, perhaps the following kind of language design would make more sense: If a variable of a type that has a destructor is passed to a function by value (moved), and the variable is used after the function call, the variable would be implicitly cloned before passing it to the function. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
On 11/06/14 01:54 PM, Tommi wrote: If the `Mul` trait and similar were changed to take `self` by value, perhaps the following kind of language design would make more sense: If a variable of a type that has a destructor is passed to a function by value (moved), and the variable is used after the function call, the variable would be implicitly cloned before passing it to the function. Cloning big integers, rationals based on big integers or arbitrary precision floating point values for every single operation has a high cost. One of Rust's strength's is that it doesn't have implicit cloning as C++ does due to copy constructors. signature.asc Description: OpenPGP digital signature ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
On 2014-06-11, at 21:33, Daniel Micay danielmi...@gmail.com wrote: Cloning big integers, rationals based on big integers or arbitrary precision floating point values for every single operation has a high cost. I didn't say that all functions should start taking their arguments by value. I said `Mul` and similar should do it, i.e. functions that take a variable and return a variable of that same type. Instead of passing by reference and making a clone of the passed reference inside those functions, you force the caller to make the clone and mutate the passed argument in place. This enables the C++ like rvalue reference optimization for functions like multiplication. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
Keeping in mind that the `self` value here can be a reference. Ie, implementing the traits also for references to a type. On Wed, Jun 11, 2014 at 11:47 AM, Tommi rusty.ga...@icloud.com wrote: On 2014-06-11, at 21:33, Daniel Micay danielmi...@gmail.com wrote: Cloning big integers, rationals based on big integers or arbitrary precision floating point values for every single operation has a high cost. I didn't say that all functions should start taking their arguments by value. I said `Mul` and similar should do it, i.e. functions that take a variable and return a variable of that same type. Instead of passing by reference and making a clone of the passed reference inside those functions, you force the caller to make the clone and mutate the passed argument in place. This enables the C++ like rvalue reference optimization for functions like multiplication. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev -- http://octayn.net/ ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev
Re: [rust-dev] self/mut self in traits considered harmful(?)
On 2014-06-11, at 21:47, Tommi rusty.ga...@icloud.com wrote: I said `Mul` and similar should do it, i.e. functions that take a variable and return a variable of that same type. Although, a larger issue of genericity is that multiplication doesn't always return the same type as one of its arguments. ___ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev