Section 4.2

For loop

The three clauses of for, the scope of its variable, and the two words that cut it short.

Counting is by far the most common use of a loop. for says it in one line instead of three.

@entry(start)
object MyProgram {
    start() {
        for (var i := 1; i <= 5; i := i + 1) {
            Console.print(text: $"i is {i}");
        }
    }
}

Five turns, from 1 to 5.

Three clauses, separated by semicolons

for (var i := 1; i <= 5; i := i + 1) {
  • var i := 1 — the initialisation, run once, before the first turn.
  • i <= 5 — the condition, tested before each turn, exactly like a while’s.
  • i := i + 1 — the step, run at the end of each turn.

It is the while from the previous subsection with its three parts gathered in one place. The gain is not brevity: it is that the step can no longer be forgotten, since it is written in the header rather than buried at the bottom of the body.

The for variable exists only inside the loop

Try reading i after the closing brace:

error[N001]: unknown name 'i'

It is local to the block. It is born at the initialisation, dies at the exit, and cannot be mistaken further down for something else. If you need the value after the loop, you need a variable declared before it.

continue skips a turn, break leaves

Two words cut a loop short — any loop, while included.

@entry(start)
object MyProgram {
    start() {
        for (var i := 1; i <= 10; i := i + 1) {
            if (i % 2 = 0) {
                continue;
            }

            if (i > 7) {
                break;
            }

            Console.print(text: $"i is {i}");
        }

        Console.print(text: "done");
    }
}

The loop counts to 10; the output stops at 7, and shows odd numbers only.

continue abandons the current turn and moves straight to the next — the step still runs. Here, if (i % 2 = 0) { continue; } skips every even number.

break leaves the loop on the spot, with no step and no further test. Here, with i at 9, the condition i > 7 holds: the loop stops and the program resumes on the line after it — hence the done.

Neither takes a label. break leaves the nearest loop, never an outer one. Two nested loops are therefore left one after the other, or through a condition you write — not by a jump.

Your turn

  • Count backwards — for (var i := 5; i >= 1; i := i - 1) — and check that the three clauses leave you free to choose the direction.
  • Read i after the loop, just to see the refusal.
  • In the second example, remove the break: the odd numbers run to 9.
  • Remove the continue instead: the even numbers come back, and 8 is what triggers the exit.