# Pre-RFC: Break with value in for/while loops

**URL:** <https://internals.rust-lang.org/t/pre-rfc-break-with-value-in-for-while-loops/11208>\
**Category:** Uncategorized\
**Created:** [October 30, 2019, 1:28pm UTC](https://internals.rust-lang.org/t/pre-rfc-break-with-value-in-for-while-loops/11208 "2019-10-30T13:28:04Z")\
**Posts on this page:** 1\
**Showing post:** 57

<div class="post-metadata">

**Author:** ![exprosic](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/exprosic/32/6521_2.png) [@exprosic](https://internals.rust-lang.org/u/exprosic)\
**Post date:** [February 8, 2020, 2:43pm UTC](https://internals.rust-lang.org/t/pre-rfc-break-with-value-in-for-while-loops/11208/57 "2020-02-08T14:43:55Z")

</div>

Coming from [https://github.com/rust-lang/rfcs/issues/1767#issuecomment-583691737](https://github.com/rust-lang/rfcs/issues/1767#issuecomment-583691737) with my proposal dumped below. I think the dispute over whether or not the loop should return an Option is completely unnecessary given the proper desugaring rule.

I would really love to have this feature, so I try to make my proposal:

- be useful in everyday situations
- have a clear and intuitive formal semantics and typing rule
- avoid the semantical confusion of `else`

Long story short, the `while` loop is followed by a `then` clause:

```rust
while BOOL {BLOCK1} then {BLOCK2}

```

This should be desugared to, and therefore have the same type and semantics with:

```rust
loop {if (BOOL) {BLOCK1} else {break {BLOCK2}}}

```

just as the usual while loop

```rust
while BOOL {BLOCK1} // then {}

```

have already and always been desugared to

```rust
loop {if (BOOL) {BLOCK1} else {break {}}}

```

It requires a bit more care for `for` but the story remains basically the same.

Note that the `break` in the `then` clause is harmless but redundant (just as the last expression in a function prefixed with `return`), since it will be desugared to `break (break ...)`.

The choice of `then` over `else` or `final` is explained in [#961](https://github.com/rust-lang/rfcs/issues/961#issuecomment-583671212)

> I would suggest `then` instead of `final`, since in all currently popular languages where it exists, `final(ly)` means the exact opposite of getting executed only when not being break-ed before, which is getting executed whatsoever. `then` would avoids the sort of naming tragedy like `return` in the Haskell community.
> 
> `then` also avoids the semantical confusion brought by `else`, since it naturally has a sequential meaning (I eat, then I walk) in parallel with its role in the conditional combination (if/then). In places where it joints two blocks (`{ ... } then { ... }`) instead of a boolean and a block (`x<y then { ... }`), the sequential semantics prevails intuitively.

This syntax can be used wherever the loop is meant to **find** something instead of to **do** something. Without this feature, we usually **do** the **finding** and then put the result somewhere, which is a clumsy emulation of just to find something.

For example:

```rust
while l<=r {
  let m = (l+r)/2;
  if a[m] < v {
    l = m+1
  } else if a[m] > v {
    r = m-1
  } else {
    break Some(m)
  }
} then {
  println!("Not found");
  None
}

```

which means:

```rust
loop {
  if (l<=r) {
    let m = (l+r)/2;
    if a[m] < v {
      l = m+1
    } else if a[m] > v {
      r = m-1
    } else {
      break Some(m)
    }
  } else {
    break {
      println!("Not found");
      None
    }
  }
}

```

Even this desugared version is cleaner than something like

```rust
{
  let mut result = None;
  while l<=r {
    let m = (l+r)/2;
    if a[m]<v {
      l = m+1
    } else if a[m]>v {
      r = m-1
    } else {
      result = Some(m);
      break
    }
  }
  if result==None {
    println!("Not found");
  }
  result
}

```

---

_[View the full topic](https://internals.rust-lang.org/t/pre-rfc-break-with-value-in-for-while-loops/11208)._
