-
Notifications
You must be signed in to change notification settings - Fork 12.1k
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
Implement Add for Vec #38573
Implement Add for Vec #38573
Conversation
I think its not delicious, as its non obvious. + can mean element wise addition just as well. |
a91d23d
to
db197ba
Compare
@est31, |
@est31, @KalitaAlexey: Python and Ruby for example. I thought JavaScript might, but it's just hilariously weird as usual... |
Other points to discuss:
|
@est31: On the topic of element-wise addition, I don't think |
This test failed, but I think whatever it was once testing has been lost in the annals of time... https://github.com/rust-lang/rust/blob/master/src/test/compile-fail/vec-res-add.rs (when it was first commited in 2011 it looked like this: cb4e99b#diff-d776888cfcb96ac7c2c3eed0a499e137) |
db197ba
to
c005906
Compare
I think implementing Depending on the specific scenario, you could want However, since we did this for |
To me, I would have expected: fn foo() -> Vec<u32> {
vec![1, 2, 3] + other_vec_func()
} ...to be equivalent to: fn foo() -> Vec<u32> {
let v = vec![];
v.extend(vec![1, 2, 3]);
v.extend(other_vec_func());
v
} It seems misleading that |
@frewsxcv: Starting with an empty vector and extending it twice is semantically equivalent to extending the first one by the second. The |
Ah, I missed this. I thought the |
Having a handy way to concatenate vectors is a nice, despite the "+" symbol is not the best for this. But the compiler has to optimize well the chains like "A+B+C+D". |
Thanks for the PR @michaelsproul! I feel like we've had this proposed before but I unfortunately can't seem to dig that up any more. I believe others on @rust-lang/libs have regretted the Also, as a libs policy, we do indeed recommend |
Given the mostly negative feedback so far, I'm happy to consider dropping this PR. I've summarised some points for and against below. For
Against
All things considered, I could go either way... |
The "cons" seem about as strong as the "pro". Regarding Python, in it you can add items to the tail of a list (dynamic array) in several ways:
The Python Zen rule "There should be one-- and preferably only one --obvious way to do it." in this case suggests to use the append(). D language is cleaner because it lacks an "extend" or "append" method, you just use the noncommutative operator with a single item:
|
Thanks for the summary, @michaelsproul! On the whole, I don't think we should merge this PR. For me, the two major factors are:
I'm not too swayed by the argument that the |
The extend you refer to is the +=, that mutates in places, that you can do in some ways:
The + is a different thing, it's a concatenation, it doesn't modify the input values (so it's good for functional-style programming, with immutables and inside expressions), and currently you can perform it with something like:
This thread discusses about adding some more expressiveness to Rust: https://internals.rust-lang.org/t/roadmap-2017-productivity-learning-curve-and-/4097 The introduction of the + between vectors allows shorter and more expressive code:
The + has indeed two meanings, to concatenate (in Python, etc) and to perform itemwise sum (in D language and others). For a person that's not expert of Rust this can lead to some confusion. |
In Python + is either concatenation or elementwise addition (list vs numpy.ndarray) and it is common for code to mix lists and ndarrays and create some confusion. (numpy is an extremely common package to use, depending on application I guess, even if it's not in Python's stdlib itself.) In this sense I think Rust, even if it has a completely different type system than Python, should not end up in this situation where Vec uses + for concatenate and other things called "Vector" or maybe "Array" use it for elementwise sum. I'm not sure what to call this, it's a near-collision of semantics.(*) For Rust examples, rulinalg defines a Rulinalg, ndarray, or others can make the clash yet worse by defining addition between their own Vector types and Moreover the current situation for String is deeply unsatisfying, and I would not want to extend this problem to Vec: |
I agree. So, is it a good idea to add a way to concatenate two vects (returning the result) in a nicer and shorter way compared to the concat() usage I've shown above?
|
Ok, in light of all the feedback, I'm going to close this PR. I think the reasons presented here are convincing, and should serve as good documentation for why this change isn't a good idea. |
In a bid to gain a little more delicious syntactic sugar, this PR implements
+
for vectors.Some operations are perfectly suited to using plus, rather than creating a mutable variable, extending it, and then returning it, like so:
Compared to using plus:
Rust's
+
is already noncommutative due to the implementations for strings, i.e. "hello" + "world" ≠ "world" + "hello", so no worries there.