-
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
Add a foreach() method to std::iter::Iterator #1064
Conversation
``` | ||
fn foreach<F>(self, mut f: F) where F: FnMut(Self::Item) { | ||
for item in self { f(item); } | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it should take &mut self
then it can be used on A) Iterators that can't be moved out from B) Iterator trait objects. Same functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Last I checked, the idea was for consuming iterator to take by value for convenience, since the by-ref behavior can be recovered with the by_ref()
adapter
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for trait objects with manual cast to &mut Iterator
rather than .by_ref()
in that case.
What is the convenience difference? I think it should be callable everywhere the self
version is.
+1, I've wanted this multiple times in the last few days. |
So far none of the points arguing against the RFC have become false:
|
What function are you referring to? The text of this RFC is intended to respond to the other points: while there are other ways to do this, they are unidiomatic, & this should not be an unidiomatic thing to do. Of course those points against remain true - so do all points in favor (none of these points are contingent on anything). This RFC has been opened because I think closing the prior RFC was a mistake. |
|
The lack of laziness in Rust means this isn't true: |
Downloads. Every version must be downloaded anew. Given the spikes and their timings in the download chart, I'm almost suspecting that a significant part of them are from brson's cargo build runs. (Many other crates have the same pattern, spikes on exactly April 3 and April 10). Edit: Some research shows one |
I hadn't considered doing this before, but it seems like a mistake: the value of chaining iterator methods to me is that they allow for a separation of concerns between each method call; it seems more appropriate to chain a |
I want this feature, but agree with @nagisa that nothing has really changed since we closed the last version of this RFC. |
A change since last RFC: It was added to itertools, so it is easily available if you accept a dependency, but it is still being requested for libstd by users. To me it seems like very basic functionality that is great to include in rust because it makes code easier to write and read. What I understand there is no rush here, we should schedule it not for 1.0 but for a later relase. |
All of the reasons in the prior RFC will always be true and are acknowledged in the text of this RFC. I understand not wanting to incentivize revisiting closed RFCs, I understand not wanting to add a whole bunch of TIMTOWTDIs to std, and I know that this RFC looks like yet-another-bikeshed, but I feel very strongly that the prior decision was mistaken in this case. The lack of this feature makes me feel like I am doing something wrong when I am doing something totally fine. This feature is not only a convenience, it also enables Rust to maintain its very strong correlation between things that are convenient and things that are good practice. |
I would like this. It feels quite strange to emphasize iterator chaining and then not provide such a method. If one is doing a complex sequence of actions with each value, using a for loop makes sense, but for situations where one is doing something simple like calling a method on each element, the syntax proposed here is much nicer. |
Pretty much all iterator chaining methods so far are executed for their results, and usually don't have side effects apart from consuming the iterator and constructing their result. Note that C# doesn't have a |
I do not agree that we should have a |
First, If this RFC is closed without acceptance, I hope it will be clarified what the exclusion of
|
Certainly, there are many valid reasons not to include it, but I have wanted this on occasion, especially when I started using Rust. At this point I don't really want it and am comfortable just using a for loop in these situations, especially given the added power therein (particularly, being able to use things like |
Thanks for the RFC @withoutboats! As others have pointed out, however, this RFC was previously closed and there hasn't be a whole lot of new developments in the meantime. This sort of addition should be backwards-compatible to do in the future, so we're not locking ourselves into never providing this for now. The standard library is in general quite conservative in the functionality it exports today as we prepare for the 1.0 release. As a result I'm going to close this for now, but if we have new developments arise we can definitely revisit! |
What new development would cause you to reopen this rfc? Rust will always have for loops & folds and the itertools crate will always compile. To be honest, it is very frustrating to have a feature that is of great practical value to me rejected for philosophical and procedural reasons. Not trying to be dramatic but this feels kafkaesque. -----Original Message----- Closed #1064. Reply to this email directly or view it on GitHub: |
Can it at least be explained why a similar addition, the std::iter::once RFC, got accepted so easily, but this RFC is getting rejected? What exactly is the difference when both are providing sugar for things you can already do? |
Given how easy it is to add the
If the
I wasn't involved with that RFC, but |
@kballard Without @alexcrichton Nothing suggested this was targeting Rust 1.0. |
That's certainly one suggestion, but the more idiomatic suggestion is to
replace it with a `for` loop.
|
I would be very surprised if the Consider someone new to Rust, who has not internalized that iterators are lazy, writing something akin to this:
It does not work! So they seek out advice, comprehend that their problem is that the iterator will never be consumed, and now write this:
This seems unambiguously less readable than the prior example. The code is now indented oddly, multiple language constructs are used which are superficially dissimilar, and the binding used in the final stage of transformation is declared at the beginning. I would be - and was - very unsatisfied with this outcome. We would be lucky if this is as far as it goes, though: being unhappy with this weird method-chain/for-loop combination, our new Rust user could refactor further:
There, that at least is familiar and consistent. But also, in my opinion, far worse! The value of It is not accurate to present the prior decision regarding this feature as inexorably determined by a set of facts, such that it would only be appropriate to raise this RFC if those facts 'materially changed.' The facts enumerated cannot materially change, as I have repeated several times. What is new about this RFC is the perspective on the question that I have presented, which I do not feel has been addressed or even responded to in this conversation. I understand that every decision cannot be constantly relegislated, but there is no established procedure for re-opening a closed RFC, so closing this pending "new developments" - which I read as "until Rust no longer supports the for loop syntax" - is dismissive at best. It has thoroughly disheartened me from participating in the RFC process. If the issue is just that the core team is too focused on May 15th to consider this issue, I do not begrudge you that at all! Please then postpone this RFC and I will bring it up again once the polishing sprint is over, but you are setting precedence that this feature is unnecessary solely on the grounds that I did not contribute to the conversation before aturon closed the prior RFC in March. |
To add to what @kballard has already said, the opinion around this RFC hasn't really changed much in the past month (as there's not strong consensus that it's needed), but if consensus were reached then we could reconsider.
Unfortunately there are a lot of features that are desired in Rust and the standard library, but we aren't able to accommodate all of them. Adding new features needs to be done with care to ensure we don't evolve too hastily and have an appropriate amount of time to evaluate the current design we have today.
To add to what @kballard said, I believe
I agree! I suppose I should have been more general in describing the current design of the standard library as conservative and less emphasize the 1.0 aspect. We do plan to grow the standard library but we intend to do so purposefully and carefully to make sure it doesn't grow too fast. I'm sorry for your frustration here, but I'd also like to emphasize that one of the greatest features of Rust is how extensible it is. Not having a feature in the standard library does not mean that it is impossible to write it in Rust, as itertools has shown. Additionally, having Cargo as a package manager means that it's super easy to add itertools as a dependency for all of your own projects. I do understand that it's not the same as being in the standard library, but the situation for being able to use a I also forgot our normal procedure of making a postponed issue for RFCs that just aren't being accepted at this time, so I've opened an issue on this topic: rust-lang/rust#24566 |
I opened an RFC issue rather than a rust-lang/rust issue: #1070 |
The primary means by which this decision would be reversed is if there's
a general widespread consensus that this is desired. If you feel that
there is such a widespread opinion and it simply hasn't been heard, I
would encourage you to open a thread on users.rust-lang.org and see what
the community there thinks. That forum isn't necessarily representative
of the whole Rust community, but it's probably better than the set of
people watching RFCs.
|
This is a re-opening of this RFC which was not merged, per the discussion in this thread.
Rendered