← Back to AILP Home

The is ternary

The is ternary is Nitpick's inline conditional expression. Its shape is:

is ( condition ) : true_value : false_value

It evaluates condition (a bool), then yields true_value when the condition is true and false_value when it is false.

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

It is an expression

Because is is an expression, it can appear anywhere a value is expected — in an initializer, a function argument, a return position, or as a sub-expression in a larger expression:

int32:x = is (c) : 1i32 : 2i32;            // initializer
pass(is (c) : 1i32 : 2i32);                // return value
int32:y = (is (c) : 5i32 : 0i32) + 10i32;  // sub-expression
println(is (c) : "yes" : "no");            // argument

Type rules

Both arms must have a compatible type, and the type of the whole is expression is their common type. If the two arms are incompatible — for example a number on one side and a string on the other — the compiler rejects it with ARIA-IS-001:

int32:x = is (c) : 1i32 : "two";           // ERROR ARIA-IS-001

When the two arms are integers of different widths, the narrower arm is sign-extended to the wider type, and the result has the wider type:

// arm types int16 and int32 -> result is int32
int32:v = is (c) : small16 : big32;

(An earlier compiler release failed LLVM verification on exactly this mixed-width case; v0.40.2 fixed it by widening the narrower arm before building the PHI node.)

Conditions are bool

Like every other condition, the is condition is strictly bool — the same rules from Conditions and bool apply, including raw fn() for a Result<bool>:

int32:x = is (raw ready()) : 1i32 : 0i32;

Variables used only in an arm

A variable referenced only inside one is arm is genuinely used — there is no false [unused-variable] warning, and borrows taken inside an arm are checked normally:

int32:a = compute();           // used only in the true arm below — still "used"
int32:x = is (c) : a : 0i32;

Common patterns

// clamp-ish selection
int32:capped = is (n > limit) : limit : n;

// default fallback
int32:port = is (configured > 0i32) : configured : 8080i32;

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