Skip to content

How to use try_fold in place of fold_while? #469

Closed

Description

@NoraCodes

fold_while has been deprecated in favor of try_fold, and will eventually be removed ( #223 ). However, there is little documentation on how to actually do this in an idiomatic way.

For example, this playground comparison is the best I could do and it looks awful. The iterator finishing early isn't an error - it's a totally acceptable condition.

I'm sure there's a better way to do this, but it would be nice to document that in fold_while or, perhaps, in try_fold (I'll be happy to open a MR for that if someone can give me a good example.)

Activity

  1. scottmcm commented on Aug 18, 2020

    @scottmcm
    Contributor

    It's true that a different impl Try makes this much nicer -- I added one to libcore that's used internally to make things like this more readable:

    https://github.com/rust-lang/rust/blob/515c9fa505e18a65d7f61bc3e9eb833b79a68618/library/core/src/iter/mod.rs#L373-L378

  2. NoraCodes commented on Aug 20, 2020

    @NoraCodes
    Author

    Oh yeah, that's much nicer! Would we be amenable to including such a construct in itertools since it's such a common case?

  3. NoraCodes commented on Aug 20, 2020

    @NoraCodes
    Author

    Actually, never mind, that's silly.

  4. jswrenn commented on Aug 20, 2020

    @jswrenn
    Member

    @NoraCodes I'll hold off on removing fold_while for the foreseeable future, at least until a more ergonomic alternative is available.

  5. NoraCodes commented on Aug 20, 2020

    @NoraCodes
    Author

    Thank you 🙏

  6. jswrenn commented on Aug 21, 2020

    @jswrenn
    Member

    This feels like an abuse of import renaming, but...

    fn main() {
        use Result::{
            self as LoopState,
            Ok as Continue,
            Err as Break,
        };
    
        println!("{}", (1..10).try_fold(0, |mut acc, v| {
            acc += v;
            if (acc >= 6) {
                Break(acc)
            } else {
                Continue(acc)
            }
        }).unwrap_or_else(|v| v));
    }

    I think this makes for a good demonstration of how to translate from fold_while to try_fold.

  7. NoraCodes commented on Aug 21, 2020

    @NoraCodes
    Author

    I actually just committed almost that exact change to our codebase. It works great, except that .unwrap_or_else(|x| x) is a little janky. But it's totally workable until something else comes along.

  8. jswrenn commented on Aug 21, 2020

    @jswrenn
    Member

    except that .unwrap_or_else(|x| x) is a little janky.

    Agreed. There's this old PR introducing Result::into_inner for situations like this, but it was unfortunately rejected: rust-lang/rust#54219

  9. added a commit that references this issue on Sep 4, 2020
  10. jswrenn commented on Sep 5, 2020

    @jswrenn
    Member

    fold_while will be un-deprecated (and slightly optimized!) our next release (0.10.0) with #476.

  11. NoraCodes commented on Sep 5, 2020

    @NoraCodes
    Author
  12. added a commit that references this issue on Sep 22, 2020
  13. scottmcm commented on Feb 7, 2021

    @scottmcm
    Contributor

    ...and I now have rust-lang/rfcs#3058 open to start moving ControlFlow towards stabilization.

  14. scottmcm commented on Jun 14, 2021

    @scottmcm
    Contributor

    Stabilization is now approved, but it'll take until September 9th to reach stable, so there's still a few months before any more work can happen here.

  15. added a commit that references this issue on Jun 15, 2021
  16. added a commit that references this issue on Mar 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions