← Back to AILP Home

Nested conditionals

Both if and is nest freely. The trick is keeping the result readable.

Nesting if

An if can contain another if, and an else if chain is itself just nesting in the else position:

if (a) {
    if (b) {
        println("a and b");
    } else {
        println("a, not b");
    };
} else {
    println("not a");
};

Prefer an else if chain over deep else { if ... } nesting when the tests are mutually exclusive:

// clearer than nested else { if ... }
if (n < 0i32) {
    println("neg");
} else if (n == 0i32) {
    println("zero");
} else {
    println("pos");
};

Nesting is

An is arm may itself be an is. Parenthesize the inner ternary for clarity:

// outer true -> inner; inner false -> 8
int32:x = is (a) : (is (b) : 3i32 : 8i32) : 99i32;

This is exactly K core test 232_is_ternary_nested_pass. Reading it: if a is true, evaluate the inner is (b) : 3 : 8; otherwise the result is 99.

Chaining is to emulate an else if ladder is possible but gets dense quickly:

int32:sign = is (n < 0i32) : -1i32 : (is (n == 0i32) : 0i32 : 1i32);

When a value selection has more than two or three cases, reach for a pick expression with give instead — see is vs pick vs when.

Mixing the two

You can compute a value with is inside an if branch, or branch with if based on a value computed by is:

int32:step = is (fast) : 10i32 : 1i32;
if (step > 5i32) {
    println("big step");
};

Keep each construct doing the one thing it is best at: if to run code, is to compute a value.