Loops

Table of contents

Overview

Carbon provides loops using the while and for statements. Within a loop, the break and continue statements can be used for flow control.

Details

while

while statements loop for as long as the passed expression returns True. Syntax is:

while ( boolean expression ) { statements }

For example, this prints 0, 1, 2, then Done!:

var x: Int = 0;
while (x < 3) {
  Print(x);
  ++x;
}
Print("Done!");

for

for statements support range-based looping, typically over containers. Syntax is:

for ( pattern in expression ) { statements }

For consistency with function parameters and other pattern matching contexts, the pattern defaults to value (immutable) bindings, like let.

For example, this prints all names in names:

for (name: strbuf in names) {
  Print(name);
}

This default can be overridden by adding the var keyword:

for (var name: strbuf in names) {
  // `name` can be modified, but this will not modify the underlying `names` container.
}

Temporary entities on the right-hand side of in remain alive during the execution of the for loop to prevent invalid memory access.

Ranged-for for user-defined types

User types can enable support for ranged-for loops by implementing the Iterate interface:

interface Iterate {
  let ElementType:! type;
  let CursorType:! type;
  fn NewCursor(self) -> CursorType;
  fn Next(self, ref cursor: CursorType) -> Optional(ElementType);
}

The cursor tracks progression, and the Next method advances the cursor and returns an Optional value. An empty Optional indicates that we have reached the end.

A for loop on a container of a type that implements Iterate behaves conceptually as (though an API for Optional has not been approved):

var cursor: range.(Iterate.CursorType) = range.(Iterate.NewCursor)();
var iter: Optional(range.(Iterate.ElementType)) = range.(Iterate.Next)(&cursor);
while (iter.HasValue()) {
  ExecuteForBlock(iter.Get());
  iter = container.(Iterate.Next)(ref cursor);
}

break

The break statement immediately ends a while or for loop. Execution will resume at the end of the loop’s scope. Syntax is:

break;

For example, this processes steps until a manual step is hit (if no manual step is hit, all steps are processed):

for (step: Step in steps) {
  if (step.IsManual()) {
    Print("Reached manual step!");
    break;
  }
  step.Process();
}

continue

The continue statement immediately goes to the next loop of a while or for. In a while, execution continues with the while expression. Syntax is:

continue;

For example, this prints all non-empty lines of a file, using continue to skip empty lines:

var f: File = OpenFile(path);
while (!f.EOF()) {
  var line: strbuf = f.ReadLine();
  if (line.IsEmpty()) {
    continue;
  }
  Print(line);
}

Alternatives considered

References