Loop Constructs Cookbook
This subsection is the canonical v0.38.8 guide for Nitpick's loop family and the
control-flow that steers it. It supersedes the older, scattered loop notes in
guide/control_flow/ and the loop fragments embedded in
guide/basics/, where those pages are shorter or stale.
The v0.38.x cycle locked the shipped behavior of every loop surface:
- the five loop forms:
while,loop(start, limit, step),till(limit, step),for x in <range/array>, and the C-stylefor(init; cond; step) - bare
break;/continue;and labeledbreak(label);/continue(label); - loop labels (
outer: while (...) { ... }) and nesting to arbitrary depth break/continuetransparency throughif, bare{ }blocks, andpickarms (whilefallstays pick-scoped)- loan release on
break, liveness acrosscontinue, and the absence of false unused-variable warnings on back-edge-only / pre-break-only variables - loop
invariantinteraction withbreakandcontinueunder both Z3 (--verify-contracts) and runtime (--debug-contracts) checking
Chapters
- Basics — the loop mental model, when to reach for each form, and the shared block/scope rules.
- while — condition-driven loops, re-evaluation, and parameter mutation inside the condition.
- loop — counted
loop(start, limit, step), the$index, and step direction / zero-step failsafe. - till —
till(limit, step), the$running value, and its desugaring toloop. - for-in —
for x in <range>andfor x in <array>iteration. - break and continue — bare control, the back-edge,
and how
continuediffers across forms. - Labeled control — loop labels,
break(label)/continue(label), and targeting an outer level. - Nested loops — nesting, innermost-by-default targeting, and multi-level escape patterns.
- Invariants and contracts — loop
invariantwithbreak/continue, entry vs back-edge obligations, and the--verify-contracts/--debug-contractsflags.
Quick mental model
- Reach for
whilewhen the stop condition is a boolean you compute. - Reach for
loop(a, b, s)when you have an explicit counter; read it via$. - Reach for
till(n, s)when you want the running value$rather than an index, counting up from0. - Reach for
for x in ...to walk a range or array element by element. break;leaves the innermost loop;continue;jumps to its back-edge.- Name a loop (
outer: while (...)) and usebreak(outer);/continue(outer);to steer an enclosing loop. break/continuesee throughif,{ }, andpickarms; onlyfallstays bound to itspick.- A loop
invariantmust hold on entry and after each back-edge.breakexits before the back-edge check;continuestill hits it.
Validation snapshot (v0.38.8)
- Compiler non-K CTest: 190/190.
- K core tests: 222/222 (adds 216–222 for while/break/continue/till).
- K proofs: 14/14.
- v0.38.x loop bug regressions: bug886–bug909.
- Loop diagnostics covered by this cycle: ARIA-LOOP-001 through ARIA-LOOP-005.
- Two compiler bugs fixed at cycle close: a PHI-node mismatch on counted-
loopinvariants under--debug-contracts, and an infinite loop when a scalar parameter is mutated inside its own loop condition.