← Back to AILP Home

Short-circuit

An is ternary evaluates its condition first, then reduces exactly one arm. The other arm is discarded unevaluated. This is true short-circuit behavior, and it is the expression-level mirror of how if runs only one branch.

// Only the true arm is reduced. `expensive()` on the false arm is never
// called when `c` is true.
int32:x = is (c) : cheap() : expensive();

Why it matters

Short-circuit lets you place a value that would be invalid or expensive on the arm that will not be taken, knowing it will never run:

// safe: the divide is only reduced when d != 0
int32:q = is (d != 0i32) : (n / d) : 0i32;

The K semantics captures this precisely. The condition is forced (strict(1)), but the two arms stay lazy, so only the selected one is ever reduced:

is (true)  : A : _   =>  A          // B is discarded unevaluated
is (false) : _ : B   =>  B          // A is discarded unevaluated

K core test 234_is_ternary_short_circuit_pass demonstrates this: its false arm contains a divide-by-zero that would error if evaluated, but because the condition is true, only the true arm is reduced and the program succeeds.

Parallel with if

The statement-level if has the same property — only the chosen branch runs:

if (true)  B else _   =>  B          // the else block never runs
if (false) _ else B   =>  B          // the then block never runs

So both conditional forms guarantee that the not-taken side has no effect: no calls, no divisions, no side effects.

Boolean operators short-circuit too

The && and || operators used inside a condition are themselves short-circuiting: a && b does not evaluate b when a is false, and a || b does not evaluate b when a is true. Combined with the arm short-circuit above, a single is can guard a chain of dependent checks:

int32:x = is (p != nullptr && raw valid(p)) : raw read(p) : 0i32;