Section 4.1

While loop

while, do/while, and the one thing that keeps a loop from running forever.

A condition, and a block redone as long as it holds.

@entry(start)
object MyProgram {
    start() {
        var left := 3;

        while (left > 0) {
            Console.print(text: $"countdown: {left}");
            left := left - 1;
        }

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

Three turns, then done.

How while goes about it

It tests the condition before each turn. If it is true, it runs the block, then starts again: test, run, test, run. As soon as it is false, it moves on to the rest of the program.

The body may therefore run no times at all. Give left the value 0 to begin with, and the program prints only done — the condition was false at the very first asking.

The line without which nothing stops

left := left - 1;

It is the most important of the three. Without it, left stays 3, the condition stays true, and the loop runs forever — the program never prints done, and has to be interrupted.

Hold on to the rule: a loop only stops if its body brings the condition closer to being false. The compiler does not check this — in general it cannot — so it is yours to keep. Try it: remove the line, run, and watch.

do / while — testing at the other end

The same loop exists with the condition after the body:

do {
    Console.print(text: $"countdown: {left}");
    left := left - 1;
} while (left > 0);

The difference fits in one sentence: the body always runs at least once, since the question is only asked afterwards. That is what you want when the action has to happen before you can decide whether to do it again.

Note the ; after the closing condition. Here the brace does not end the statement — the condition follows it, and the semicolon closes.

Your turn

  • Set left to 0 to begin with: the loop does not run once.
  • Remove left := left - 1; and run it. You will see what an endless loop is — here the sandbox stops it because the output grows too long, and says so. Without that guard, it would run forever.
  • Rewrite the loop as a do/while with left at 0 to begin with, and compare: it prints one line where while printed none.