ilo has no if/else. This is the single design decision that most reduces nesting depth in AI-generated code.
The nesting problem
In a traditional language, conditional logic stacks:
def process(x, y, z):
if x > 0:
if y > 0:
if z > 0:
return x + y + z
else:
return x + y
else:
return x
else:
return 0
Each level of nesting adds indentation, a closing brace, and state the agent has to track. Deep nesting means the agent is holding the entire conditional tree in working memory while generating each token.
Guards are flat
In ilo, the same logic is a series of guard statements:
f x:n y:n z:n>n
<=x 0 0 -- if x <= 0, return 0
<=y 0 x -- if y <= 0, return x
<=z 0 +x y -- if z <= 0, return x+y
++x y z -- default: return x+y+z
Each guard is an independent statement: condition, then return value. If the condition is true, return immediately. Otherwise, fall through to the next line. No nesting. No closing braces. Depth stays constant regardless of how many conditions there are.
The agent emits each guard and moves on. It doesn’t need to track where it is in a tree.
Match instead of switch
ilo also has ? for exhaustive matching - the equivalent of switch/case but without fall-through:
?result{
~v: v -- Ok: return the value
^e: 0 -- Err: return 0
}
Each arm is independent. There’s no execution path between arms, no break to forget, no bleeding from one case to the next. Fall-through bugs are structurally impossible.
The token argument
Guards save tokens two ways. First, no else keyword - the fall-through is implicit. Second, no closing braces to match. In deeply nested code, closing braces can be 20-30% of the token count. Guards eliminate them entirely.
More importantly, guards reduce retry tokens. Nested conditionals are where AI-generated code most often goes wrong - wrong nesting level, mismatched braces, logic in the wrong branch. Guards make the correct structure obvious at each generation step.
What you lose
The one thing guards can’t express as cleanly is an else arm on the same condition - where you want to do one thing if true and something else if false, and then continue. For that, ilo has ternary guards with two bodies:
>x 0 {pos-result}{neg-result}
Most conditional logic is early-return: validate inputs, handle edge cases, then the default at the bottom. Guards fit that pattern.