12
$\begingroup$

The Rust programming language has an infinite loop construct, which looks like this:

loop {
   <some code>
}

It's the only language I can think of that has dedicated syntax for this; in most other languages some variation of while true is used instead. Why does Rust have it?

$\endgroup$
6
  • 1
    $\begingroup$ Although it isn't necessarily good practice, note that this can also be replicated in C (and some other languages), such as with #define forever while (1) and then you can just do forever { ... } $\endgroup$
    – cocomac
    Commented May 19, 2023 at 17:23
  • 1
    $\begingroup$ Ruby has this too $\endgroup$
    – naffetS
    Commented May 19, 2023 at 17:25
  • $\begingroup$ QBasic has something similar with DO ... LOOP, although you can also add a WHILE or UNTIL condition to either the DO or the LOOP. $\endgroup$
    – DLosc
    Commented May 19, 2023 at 22:25
  • 1
    $\begingroup$ Ada has loop ... end loop, in part because of exit (C/Rust break)/return statements and in part because of a need to loop infinitely in some low-level programs. $\endgroup$
    – prosfilaes
    Commented May 21, 2023 at 14:19
  • $\begingroup$ Go also has for { ... } which is the same as for ;; { ...}. $\endgroup$
    – user623
    Commented May 27, 2023 at 10:01

3 Answers 3

23
$\begingroup$

The rust loop {} syntax has a unique feature: it has a return value. Consider this code:

let val = loop {
   let random_number = rng::random();
   if random_number < 0.5 {
       break random_number;
   }
}

This will set val to the first random number below 0.5. This wouldn't work for any other kind of loop since they could potentially exit before hitting a break.

Other languages don't have this because they have statements distinct from expressions, so loops don't return anything. In rust all other loops return ()

This feature was actually added later, initially the loop{} construct existed as the only way to create a ! "never" type.

$\endgroup$
8
  • $\begingroup$ Great answer! I actually used it for exactly this just yesterday, to implement Parsec's many :: Parser a -> Parser [a] in Rust. Loop until you get an Err then break and check the error. $\endgroup$ Commented May 19, 2023 at 17:32
  • 2
    $\begingroup$ Worth adding that while loops cannot have the same feature, because they might terminate without breaking. A language could have while loops which produce optional values, but this would be inconvenient for the use-case where the only loop exit is a break which does produce a value. $\endgroup$
    – kaya3
    Commented May 20, 2023 at 3:15
  • 5
    $\begingroup$ while and for loops could have the same feature if they also have an else clause, which only executes when the loop does not exit via break. Python is the most well known language that supports an else clause after loops, but the only language I'm aware of that also supports while ... else and for ... else returning values is Zig. $\endgroup$
    – Olive
    Commented May 20, 2023 at 6:04
  • $\begingroup$ One way this could possibly be implemented for while loops is using the value of the last expression in the block if it terminates due to the condition (like other constructs do). E.g., let mut x = 10; while x > 4 { x -= 1; x * 2 } would return 8 $\endgroup$
    – rydwolf
    Commented Jun 27, 2023 at 14:05
  • 2
    $\begingroup$ This explanation is anachronistic. Return values were only added to loop in 2016, so they cannot be possibly the reason the loop construct exists in the first place. $\endgroup$ Commented Jun 27, 2023 at 15:43
8
$\begingroup$

loop was originally added to Rust to allow for functions whose body was an infinite loop to not need a return statement after the loop. Other languages get around this by treating loops as definitely infinite only when the controlling expression is the literal true (e.g. Dart, TypeScript) or a compile-time constant that evaluates to true (e.g. JLS§14.22, Zig, D).

$\endgroup$
4
$\begingroup$

While loop may have been added with returning values in mind, making this just a bonus, infinitely looping until a break is encountered is pretty common across languages (with constructs like while (1) or for (;;) likely being familiar to most), and giving this dedicated syntax saves keystrokes and improves readability.

E.g., Ruby has this loop syntax (along with a similarly sugary until), yet doesn't have the value-returning feature, showing that the readability advantage is itself worth considering in a vacuum.

$\endgroup$
1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .