Conditions and iteration
This guide explains how to express a deterministic business rule in Touba. A computable decision does not need a model.
Choose a path
if / else if / else evaluates conditions in order and runs the first
selected branch. Each condition must be a Boolean. These controls compose
inside functions, skills and strategies.
module examples.triage
type Ticket
id is Text
overdue_days is Int
active is Boolean
function FirstAction
takes tickets as List of Ticket
gives Optional of Text
do
for ticket in tickets
if ticket.active
if ticket.overdue_days >= 7
give some("Urgent: " ++ ticket.id)
else if ticket.overdue_days >= 3
give some("Follow up: " ++ ticket.id)
give none(Text)
The function walks tickets in input order and returns an action for the first active ticket needing attention: urgent from seven days, follow-up from three days. If none matches, it returns absence. It does not sort tickets by urgency.
Iterate without implicit mutation
for item in itemswalks a typed list in order.bindandintoresults are local to their block; they do not reassign a variable in the caller's scope.giveends the current call, including from a nested loop.whileuses the host limitmax_loop_iterations(100 by default). Reaching this limit produces a runtime refusal. There is no sourcemax_iterationsclause. See the syntax reference.
A loop does not introduce a mutable accumulator. To transform each item into
a result, use a typed target inside a strategy or skill and
bounded parallelism. For a first-match search,
a for loop with an early return is appropriate.
Preserve execution controls
module examples.bounded_loop
function Wait
takes repeat as Boolean
gives Text
do
while repeat
bind observed as Boolean = repeat
give "Ready"
touba compile bounded-loop.tb --out bounded-loop.air.json
touba run bounded-loop.air.json --entry function:examples.bounded_loop/Wait --inputs-json '{"repeat":false}' --max-loop-iterations 3 --output json
With false, the result is Ready. With true, the host stops the loop after
three iterations. CLI option --max-loop-iterations sets the runtime's
max_loop_iterations limit.
Repeating a call grants no additional authority. Declared capabilities, grants, scopes and run budgets remain checked on every call. An authorized capability may be used repeatedly while its constraints permit it.
Loops and conditions do not prevent human pauses: the continuation preserves the calls and scopes needed for resumption. See Durable recovery to choose the right mechanism.
Try it
The classification tutorial combines enums, optionals and branches with JSON inputs and verifiable results.
For a closed enum choice, use match / case. The compiler checks that every member is handled exactly once.