← Back to AILP Home

if / else if / else

The if statement runs a block when its condition is true. It may be followed by zero or more else if clauses and an optional trailing else.

func:grade = int32(int32:score) {
    if (score >= 90i32) {
        println("A");
    } else if (score >= 80i32) {
        println("B");
    } else if (score >= 70i32) {
        println("C");
    } else {
        println("F");
    };
    pass(0i32);
};

Evaluation order

Conditions are tested top to bottom. The first one that is true runs its block; all remaining clauses (including else) are skipped. If none is true and there is an else, the else block runs; otherwise nothing runs.

This is the statement-level mirror of the is ternary's arm selection, and the K semantics encodes exactly these cases:

if (true)  B else _   =>  B
if (false) _ else B   =>  B
if (true)  B          =>  B
if (false) _          =>  .K        // nothing runs

Blocks and scope

Each arm is its own block with its own scope. A binding introduced in one arm is not visible in another arm or after the if:

if (c) {
    int32:t = compute();   // `t` lives only in this arm
    use(t);
};
// `t` is not in scope here

A variable declared before the if and used in only one arm is still a genuine use — you will not get a false [unused-variable] warning:

int32:limit = 10i32;       // used only in the then-branch below — still "used"
if (c) {
    pass(limit);
};

else if is a nested if

else if is not a separate construct; it is an if statement in the else position of the previous one. That is why an assignment typo in an else if condition produces the same ARIA-IF-002 diagnostic as one in the leading if (see Diagnostics).

Dead code after a terminating branch

If a branch ends by leaving the function — for example via exit — any code after the whole if that can only be reached when that branch did not fire is still live. But code placed after an unconditional exit within a block is dead, and the compiler flags it:

if (c) {
    exit 3i32;
    println("never runs");   // [dead-code]
};