This library is in flux. APIs may change without notice. Generated from source on 6/15/2026.
Control
Provides ~if for zero-overhead conditional branching
control.kz
Koru Standard Library: Control Flow
Provides ~if for zero-overhead conditional branching
ARCHITECTURE: ~if is a pure comptime transform that generates inline Zig code.
- ~if(expr) | then |> ... | else |> ... becomes a literal if/else statement
- No function call overhead, full access to outer scope
- Uses template_utils.lookupTemplate + interpolate for metaprogramming!
// IF - Conditional as a template over the continuation-return mechanism.
//
// Syntax: ~if(cond)
// | then |> ... // optional: runs when cond is true
// | else |> ... // optional: runs when cond is false
//
// ARCHITECTURE:
// - ~if is a |template|zig proc, NOT a dedicated AST node (no ConditionalNode).
// The body is a literal Zig if/else. `then` / `else` are TERMINAL
// continuations, CONTINUED by the template via `{{ continuations["X"].continue }}`
// — the same producer→consumer dispatch every branched event uses. Where
// `for` CALLS effects during the loop, `if` CONTINUES to one of its terminals in
// the matching arm. Same machine; `if`'s "during" half is just empty.
// - Zero-overhead: the consumer's `then` / `else` body is spliced into the
// matching arm in the enclosing scope. An omitted optional branch mints no
// marker, so its arm renders empty.
~[keyword]pub event if {
cond: []const u8
}// ============================================================================
// FOR - Iteration as a template over the effect-branch engine (ZERO OVERHEAD)
// ============================================================================
//
// Syntax: ~for(iterable_expr)
// ! each item |> process(value: item)
// | done |> finalize() // optional: runs once after the loop
//
// ARCHITECTURE:
// - ~for is a |template|zig proc, NOT a dedicated AST node. The body is a
// literal Zig `for`; each `! each` effect handler is called inside it
// (guarded by its `when`, if any). The optional `| done` terminal is RETURNED
// via `{{ continuations["done"].continue }}` — the producer→consumer dispatch,
// not an emitter append. Effects are called during; continuations returned.
// - The `! each` handlers lower to a synthesized Handlers struct + in-scope
// alias (emitter inline-body bridge); the template references each by link
// and emits a guarded call. No ForeachNode. Mirrors `if` above (pure
// continuation-return); `for` and `if` are one mechanism.
// - Zero-overhead: comptime-known handlers inline into the loop.
~[keyword]pub event for {
iterable: []const u8
}// ============================================================================
// CAPTURE - Accumulation with pure semantics (ZERO OVERHEAD)
// ============================================================================
//
// Syntax: ~capture { total: 0 }
// ! as acc |> for(items)
// ! each i |> captured { total: acc.total + i }
// | captured final |> result(sum: final.total)
//
// Both `capture` and `captured` take a SOURCE BLOCK — bare braces, no parens.
// Bare `name { ... }` is unambiguously an invocation since the `=>` construct
// glyph took over branch construction (210_047). The parens forms
// `capture({...})` / `captured({...})` are retired (ratified 2026-06-11).
// A block holding a single bare expression (`~capture { entity }`) seeds from
// an existing value instead of building a new struct cell.
//
// ARCHITECTURE:
// - ~capture is a comptime transform: `! as` binds the cell (live/during),
// `captured { ... }` invocations are rewritten into general `.assignment`
// nodes, `| captured` is the one-shot after-read.
//
// SEMANTICS:
// - Pure from Koru's perspective (captured computes the NEXT value)
// - Efficient mutation in generated Zig (var cell + field writes)
// - Decomposes fold while preserving purity guarantees
// The event declares the USER surface (second [transform]proc migrant after
// std/regex:match): a source block, the `! as` cell effect, the optional
// `| captured` after-read. The shape checker enforces this contract with zero
// capture-specific code. The machine interface (invocation/item/program/
// allocator → transformed SiteResult) is the proc-return convention.
~[keyword|comptime|transform]pub event capture {
source: Source
}// ============================================================================
// CONST - Immutable bindings for pipelines
// ============================================================================
// ~const({ threshold: 5 }) | as cfg |> ...use cfg.threshold...
//
// Much simpler than capture:
// - No mutation, so no `captured` branches to transform
// - No runtime struct type conversion needed
// - Just binds constants and flows through
//
// CONST - module-level value declarations as a per-target TEMPLATE.
//
// Syntax: const { name: "Claude", count: 42 } (newline- OR comma-separated)
//
// ARCHITECTURE: `const` is a |template| proc over a `source: Source` block —
// NOT a transform. The block is captured WHOLE as a Source (no first-field
// truncation), and the `parse_fields` Zig FILTER (template_processor.zig) splits
// it into `{ name, value }` records. Both the |zig| and |js| variants call that
// SAME filter, so the two lowerings of a const block cannot drift. Each field
// becomes a `const name = value;` declaration; values are emitted verbatim, and
// per-target value shaping (a future `comptime_int` vs `number` split) rides the
// variant boundary — exactly like `if`/`for`. This replaces the old
// transform-+-codegen_utils.koruStructToConstDecls path ("emit Zig and hope").
// `[declaration]`: this keyword template emits DECLARATIONS (names into the
// enclosing scope), not a statement. The emitter splices a declaration flow's
// rendered body directly at container scope (struct members), NOT wrapped in a
// `flow()` function — so sibling flows see the names via Zig container-scope
// lookup. Contrast `if`/`for`, which emit statements into a function body.
~[keyword|declaration]pub event const {
source: Source
}