Loop Basics
Nitpick ships five loop forms. They share one block-and-scope model and one
control-flow vocabulary (break, continue, and their labeled variants), so
once you know the shape of one, the others follow.
The five forms
| Form | Shape | Use when |
|---|---|---|
while |
while (cond) { ... } |
the stop condition is a boolean you compute |
loop |
loop(start, limit, step) { ... } |
you have an explicit counter ($ = index) |
till |
till(limit, step) { ... } |
you want the running value ($), counting from 0 |
for-in |
for x in <range/array> { ... } |
you walk a range or array element by element |
C-style for |
for(init; cond; step) { ... } |
you want the classic three-part header |
A first example
func:failsafe = int32(tbb32:err) {
exit 1;
};
func:main = int32() {
int32:total = 0i32;
loop(0i32, 5i32, 1i32) {
total += $;
}
exit total; // 0 + 1 + 2 + 3 + 4 = 10
};
Shared rules
- Every loop body is a block. Variables declared inside the body are scoped to one iteration and are re-created on each pass.
- The condition (or counter check) is re-evaluated before every iteration,
including after a
continue. break;leaves the innermost enclosing loop.continue;skips to that loop's back-edge (its next condition / step check). See break and continue.- A loop may carry a name and an
invariant. See Labeled control and Invariants and contracts.
Choosing a form
Prefer the most specific form that fits. A counted walk reads better as
loop(0i32, n, 1i32) than as a hand-rolled while with a manual counter, and
a range walk reads better as for x in 0i32..n. Reserve while for the cases
where the stop condition genuinely is a computed boolean.
Next: while.