# Pre-RFC: \`while let ... break\`

**URL:** <https://internals.rust-lang.org/t/pre-rfc-while-let-break/19345>\
**Category:** language design\
**Created:** [August 16, 2023, 6:34pm UTC](https://internals.rust-lang.org/t/pre-rfc-while-let-break/19345 "2023-08-16T18:34:04Z")\
**Posts on this page:** 4\
**Page:** 2

<div class="post-metadata">

**Author:** ![Vorpal](https://avatars.discourse-cdn.com/v4/letter/v/aca169/32.png) [@Vorpal](https://internals.rust-lang.org/u/Vorpal)\
**Post date:** [August 18, 2023, 4:27am UTC](https://internals.rust-lang.org/t/pre-rfc-while-let-break/19345/21 "2023-08-18T04:27:15Z")

</div>

The disagreement really is over how common this pattern is in relation to how exotic the syntax is.

Yes, you can do without for loops, but it is a very common pattern and it is well established in all imperative languages.

This pattern i have never come across, in my domain retry logic tends to be far more complicated and specified in an explicit FSM (if the robot arm did not reach the target point before the timeout triggered, do a recovery action, up to N times, but if the hydraulic pressure ever goes outside a specific range abort immediately). As such, simplistic retry like this just isn't useful. I also haven't seen this sort of pattern in any of the command line tools I have written.

Probably there is a domain where this _is_ useful and common, but an RFC would need to motivate the need for the feature by demonstrating that, and that it is in fact useful across a _broad_ number of domains, not just a single one.

---

<div class="post-metadata">

**Author:** ![afetisov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/afetisov/32/8508_2.png) [@afetisov](https://internals.rust-lang.org/u/afetisov)\
**Post date:** [August 18, 2023, 5:32am UTC](https://internals.rust-lang.org/t/pre-rfc-while-let-break/19345/22 "2023-08-18T05:32:16Z")

</div>

> [@canndrew](#):
>
> Something I want regularly (and which has been suggested before) is for `for`/`while` loops to have an optional `else` block that executes if the loop reaches the end without breaking.

Rust isn't Python. Rust is expression-based, which means the code you want can already be expressed, without the ambiguities of Python's for-else construct:

```rust
fn foo<T: PartialEq>(
    pred: impl Fn(&T) -> bool,
    iter: impl Iterator<Item = T>,
) -> Option<T> {
    let val = 'block {
        for val in iter {
            if pred(&val) {
                break 'block Some(val);
            }
        } 
        None
    };
    // do stuff with val
}

```

The specific function you wrote can be more clearly expressed both in Rust and in Python:

```rust
fn iter_find<T: PartialEq>(
    pred: impl Fn(&T) -> bool,
    iter: impl Iterator<Item = T>,
) -> Option<T> {
    for val in iter {
        if pred(&val) {
            return Some(val);
        }
    } 
    None
}

```

---

<div class="post-metadata">

**Author:** ![crlf0710](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/crlf0710/32/1987_2.png) [@crlf0710](https://internals.rust-lang.org/u/crlf0710)\
**Post date:** [September 26, 2023, 3:49am UTC](https://internals.rust-lang.org/t/pre-rfc-while-let-break/19345/23 "2023-09-26T03:49:15Z")

</div>

Library level solution that outputs 0 to 5:

```rust
use std::ops::ControlFlow::{self, *};

trait Repeat<Arg, Ret> {
    fn repeat(&mut self, arg: Arg) -> Ret;
}

impl<T, Arg, Ret> Repeat<Arg, Ret> for T
where
    T: FnMut(Arg) -> ControlFlow<Ret, Arg>,
{
    fn repeat(&mut self, mut arg: Arg) -> Ret {
        loop {
            match (*self)(arg) {
                Break(b) => return b,
                Continue(c) => arg = c,
            }
        }
    }
}

fn main() {
    let mut print_x = |i: i32| {
        println!("{i}");
        if i >= 5 {
            Break(())
        } else {
            Continue(i + 1)
        }
    };
    print_x.repeat(0)
}

```

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [December 25, 2023, 3:50am UTC](https://internals.rust-lang.org/t/pre-rfc-while-let-break/19345/24 "2023-12-25T03:50:02Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.

[Previous page](https://internals.rust-lang.org/t/pre-rfc-while-let-break/19345.md?page=1)
