-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
std::vec::Vec's sort methods should return &mut Self #2178
Comments
That would prevent in-place sorting as it requires allocation of a new |
Did you mean |
@sinkuu ah, yes, thank you! |
This is a breaking change. |
I think Your initial example makes it very clear that there's an intermediate allocation, and not a zero cost iteration. |
In Python the functions that work in-place, like sort() return None, this helps remember their semantics. In Python you also have sorted() that clones the input sequence into a new list, sorts it, and returns it. A handy sorted() is also present in the Rust itertools crate (but it currently lacks the key, and unstable versions): https://docs.rs/itertools/0.7.2/itertools/fn.sorted.html D language standard library solves this ergonomy/correctness problem of sort in a different way: https://dlang.org/phobos/std_algorithm_sorting.html#.sort In D sort() doesn't return void, nor it returns the sorted array. It returns a SortedRange, and you can get the sorted array calling a release() method on it. This makes sort() usable in range chains, where it doesn't break the chain (unlike Rust sort functions), but at the same time the ".release()" after the sort makes it clear that it not a regular function and works in-place. A SortedRange is also useful for many other purposes (it supports binary searches and other similar searches, a filter() on a SortedRange could return another SortedRange, etc). |
This is not actionable due to the breaking change so I'll close this. |
What about a method |
+1, this is not breaking and would be useful |
Is this |
An extension trait can easily be written: trait VecExt {
fn sorted(self) -> Self;
}
impl<T> VecExt for Vec<T>
where
T: std::cmp::Ord,
{
fn sorted(mut self) -> Self {
self.sort();
self
}
} fn main() {
let blob = "cwrxwzbgickpjbp";
let result = blob
.chars()
.collect::<Vec<_>>()
.sorted()
.into_iter()
.count();
} Rinse and repeat for each variation of sorting. |
Or make it extremely generic: trait Tap {
fn tap(self, f: impl FnMut(&mut Self)) -> Self;
}
impl<T> Tap for T {
fn tap(mut self, mut f: impl FnMut(&mut Self)) -> Self {
f(&mut self);
self
}
} fn main() {
let blob = "cwrxwzbgickpjbp";
let result = blob
.chars()
.collect::<Vec<_>>()
.tap(|v| v.sort())
.into_iter()
.count();
} |
For what it's worth, Swift has a dedicated verbiage for this throughout the language: methods ending in I think having this in Rust would add a nice consistency if followed in other parts of the language! (I'm new to Rust so I'm not sure if other parts of the language already have this sort of convention.) Edit: #2731 appears to address this |
It now supports the other variants as well :-) https://docs.rs/itertools/latest/itertools/trait.Itertools.html#method.sorted |
Now I'd like those sorted() variants in the stdlib :) |
Just did a little string-based challenge to train my Rust and stumbled, when I wanted to chain several calls, but could not do so, because
std::vec::Vec
'ssort_by()
returns()
instead ofSelf
. Imho, this is a very small change which would make life easier and code cleaner. Example:Instead of this
I would love to write this:
All sort methods have the same problem, so I would propose to change them so they return
&mut Self
and can be chained.The text was updated successfully, but these errors were encountered: