Skip to content
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

RFC: add try_all and try_any to Iterator #3233

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

FlixCoder
Copy link

@FlixCoder FlixCoder commented Feb 16, 2022

rendered

Hi!

As this is my first RFC / PR here, I am sorry if there is something missing or wrong.

Thank you for reviewing and suggestions :)

@FlixCoder FlixCoder changed the title Proposal to add try_all and try_any to Iterator RFC: add try_all and try_any to Iterator Feb 16, 2022
@nrc nrc added the T-libs-api Relevant to the library API team, which will review and decide on the RFC. label Feb 18, 2022

Adding new methods to the trait makes it even bigger, but I would argue that is a low cost (especially in this small case) for a nice benefit.

# Rationale and alternatives
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can there be a general adapter for these?

I did recently r+ try_collect for nightly (rust-lang/rust#94041), but now I'm wondering if instead of having all of these -- especially for non-adapters -- we should expose the shunting mechanism that they use somehow instead.

Notably, the .try_collect() could plausibly be exposed as .try_mut(|i| i.collect()), so I wonder if there'd be a way that try_all and try_find and friends could also be exposed via a similar mechanism. (And thus remove try_collect and try_find and such from the trait altogether. try_fold is a slightly different case as it's there to be the internal iteration primitive, and is only secondarily there as something to be used directly.)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, I am not sure if I fully understood it, but from the looks it does indeed look nice to have the try_process available through e.g. try_mut/try and it could possibly be used for all the iterator methods to for Try types. If try_all and try_any would be as simple as iter.try(|i| i.all(check)) or iter.try().all(check). The naming would be a point though, I am not sure if that would be very discoverable and whether it really works.
The latter possiblity would also be a bigger one, yet more flexible. It would need to return something new with new implementations probably.

Nevertheless, I think it makes a lot sense to go for a way that allows using Try in all the iterater-consuming methods. It would be a different and bigger change probably and one needs to make sure things like .try_mut(|i| i.next()) and .try_mut(|i| i.map()) behave as expected. For map I am quite sure it cannot behave up to expectations, as it just returns a new iterator and doesn't iterate.

If we would still go for adding try_ methods, they should at least be able to use that method internally.

Copy link

@timvermeulen timvermeulen Aug 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is unlikely (without major language changes).

try_find/try_all/etc have to deal with a closure, which makes them a lot more complicated than try_collect. If you wanted to implemented try_find in the shape of .try(|i| i.find(...)) then you'd have to return a bool from the closure, but you have a closure that returns an impl Try<Output = bool>. So how do you handle a failure? There are two hurdles:

  • The closure needs to communicate to the iterator that a failure has happened and iteration can stop. This probably requires having a struct that wraps the given closure and implements the Fn* traits.
  • After reporting the failure, the closure still needs to return something (a bool in this case). It doesn't even matter much what it returns, as the iteration stop before the next element anyway, but it needs to return something. A Default bound might solve it for most methods, but what about e.g. try_max_by_key?

We can almost get there, but not quite all the way it seems. Implementing non-try methods in terms of their try counterparts is, of course, a lot simpler.

@FlixCoder
Copy link
Author

So I am unsure now, are you waiting for something from me?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-libs-api Relevant to the library API team, which will review and decide on the RFC.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants