← Back to AILP Home

Overview

when is a loop with a built-in answer to one question: did the loop finish its work, or was it cut short? A plain while loop cannot tell you — you have to thread a boolean flag through the body yourself. when folds that flag into the language and routes control to one of two completion blocks.

Shape

when (condition) {
    // body — runs while `condition` is true, exactly like `while`
} then {
    // runs once, if the loop exited cleanly
} end {
    // runs once, if the loop was cut short
}

Both then and end are optional. The body behaves identically to a while loop: the condition is re-evaluated before every iteration, the body is a fresh scope each pass, and break / continue work as they do in any loop.

The completion decision

After the loop stops, exactly one of then or end is eligible to run:

How the loop stopped Block that runs
condition went false after ≥ 1 full iteration then
condition was false from the start (0 iterations) end
a break fired end

Read it as two flags — completed (a body iteration reached the back-edge) and broke (a break fired):

then  ⇐  completed && !broke
end   ⇐  broke || !completed

then is the "happy path" — the loop did its job and ran out of work. end is the "short-circuit path" — either nothing happened, or someone bailed out early.

A worked example

func:failsafe = int32(tbb32:err) {
    exit 1;
};

func:main = int32() {
    int32:i = 0i32;
    int32:sum = 0i32;
    when (i < 5i32) {
        sum = sum + i;
        i = i + 1i32;
    } then {
        sum = sum + 100i32;   // clean exit -> add the bonus
    } end {
        sum = sum + 1i32;     // unreachable here: the loop always completes
    }
    exit sum;                 // (0+1+2+3+4) + 100 = 110
};

The loop sums 0..4, the condition goes false after the fifth check, and — because at least one iteration completed and no break fired — then runs.

Where to go next