-
Notifications
You must be signed in to change notification settings - Fork 324
Non-assignment binary operations shouldn't mutate input #83
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I guess it's intentional, I didn't think too much about this choice. Which do you expect:
As it is, it's useful to some extent since it allows That would have to be replaced by |
Unfortunately we will maybe not get rid of the
|
Isn't there the 3rd option of never doing the operation in place and instead cloning the array, doing the operations on the clone, and then returning it? I don't necessarily expect For rvalues, there are already some examples in the tests, which demand binding the view to an lvalue first. While needing one more line, I think doing the below is fine: let mut asliced = a.slice_mut(s![..4, ..4]);
asliced += 1.0; But I have a feeling I misunderstood the issue. |
That sounds like the second alternative, return OwnedArray. |
Which way would have performance as primary objective? I think a + b must be good. Right now &a + &b creates a new array for the result and a + b reuses the allocation in a. |
@vbarrielle What do you think? |
I haven't played with the binary operations for the moment, I'll have a look. |
I've been playing a bit with @SuperFluffy's example. I find the behaviour on mutable views surprising,it might be a pain point for users. I also feel that having I'm thinking there could be a way to keep this feature without having a surprising behaviour:
|
There's a summary here actually https://bluss.github.io/rust-ndarray/master/ndarray/struct.ArrayBase.html#arithmetic-operations I'm reading your thoughts, but I wanted to say that there are more combinations, for example that |
We can easily take the step to remove the ArrayViewMut impls, just to test what happens. Is an in place operations view necessary? The user still as |
No it's not necessary, repeated calls to Simply removing the impl on ArrayViewMut would be a good move imho.
Ok I had not seen those. Well I think it still makes the allocation somehow explicit, ie there is no way the result could be written into A. In summary: I like the current implementation of binary operations, except for the ArrayViewMut impl part. |
Thank you for your thoughts! I think we will remove the ViewMut impls. I'll update the arithmetic ops overview, I think it's quite necessary to have a summary when there are so many There is very good news -- all in place operators are being stabilized for Rust 1.8. |
It's nice that in place operators are getting stabilized! Can't wait to use them. |
Maybe with impl specialization landing sometime in the future, the impls on |
…e `B` Previously, operators like +, - etc, denoted by @ in general, were implemented so that they allowed ArrayViewMut as the left hand side operand. It would update the data in the view, and return the same view. This can be confusing, and was suggested by @SuperFluffy to be removed. We tentatively remove those implementations here. To work around B @ A not being allowed for a mutable view `B`, you can use B @= A instead, or the corresponding stable methods iadd, imul, etc. Please see the Arithmetic Operations overview in the `ArrayBase` docs for an easy to read overview. Fixes #83
Not sure if specialization impacts this or not. Maybe it can be implemented with a different behavior already now. However, the use of generics in this crate is already very complicated. We want to have some logical system that the users will understand — it seems easier to just leave this unimplemented in that case. |
In the example at the bottom, addition of two arrays yields a new one, but also mutates one of the inputs. This is because the
add()
function in theAdd
trait is defined in terms of the in-placeiadd()
(from the macroimpl_binary_op
macro):This is fine, if self is an
OwnedArray
or anArray
because they are consumed anyways, but if instead anArrayViewMut
is passed in, the underlying data changes. Is this intended? I think one shouldn't expect the array to get changed when addition is performed on a view.The text was updated successfully, but these errors were encountered: