This library is in flux. APIs may change without notice. Generated from source with koruc 0.1.7 on 11/4/2026.

Ctx

import std/ctx

Koru Standard Library: ctx — lexical scope injection.

ctx.kz · 1 tors

Koru Standard Library: ctx — lexical scope injection. · 52 more lines
Koru Standard Library: ctx — lexical scope injection. |> std/ctx(outer) |> my/verbs:probe() |> std/ctx(inner) |> my/verbs:probe() `std/ctx(X)` is the module's `default` tor — a bare-name attach, same convention as `std/store(game)` / `std/pump(main)`. A `ctx(X)` step is a compile-time scope: the transform walks its continuation subtree and, for every invocation, fills params the call left unfilled from the nearest enclosing scope providing a field of the same name AND a type that fits the param — the author spelling `call()` while the emitted call reads `call(a: inner.a, b: outer.b)`. Scope = downstream continuation subtree, so a linear `ctx(A) |> ctx(B) |> call()` chain shadows A with B for the call; arms, conditionals, and nested chains all inherit. The ctx step itself is spliced out — zero runtime cost: injection is argument-filling at compile time, nothing resolves at run. precedence: explicit arg > innermost compatible ctx > outward ctx > declared default > ordinary missing-param refusal (automatic — nothing new) Matching is name + exact canonical type: a same-named column whose type cannot serve the param does NOT shadow — it falls through to outer scopes, so `ctx(inner) |> ctx(outer)` with `inner.a:f64`/`outer.a:i64` feeds `a: i64` params from outer and `a: f64` params from inner. A param no compatible scope provides stays unfilled and refuses through the ordinary missing-input path. TODO(projection): scope spelling is planned to take a capture-shaped map — `std/ctx { fs: theme[r].fs, sel: docs[cur] }` — presenting names bound to arbitrary backing exprs (ScopeBinding's {name, type, value_ref} shape). Types resolve off store-field paths; arbitrary exprs need inference or an explicit type in the map. Clone keys + free-var lifting follow the same rules as subscripted scopes. TRANSITIVITY — the scope crosses the subflow boundary. When a call under a scope targets a koru-bodied tor whose body (transitively) consumes a scope field, the callee is cloned keyed on the scope stack: `ctx(inner) |> needs-scope()` emits `needs-scope__ctx_inner`, whose body is the original's with injection applied under the stack. Free variables in scope expressions lift into clone params — `ctx(themes[i])` produces `themes[__ctxarg0]` inside the clone, bound per call site — so `themes[i]` and `themes[j]` share one clone. Host-proc tors have no body to clone; their declared inputs still inject at the call site. The scope value is a source expression naming a store — `world`, `themes[h]`, `cfg`. Which fields a scope provides is read off the schema of the store it names (the `std/store:new` seed block — name AND column type); a scope that names no store provides nothing. Calls whose decl has no input shape in this program pass through untouched. Promoted from the libs/ctx experiment (koru-libs commit 60b20a3).

default

keywordcomptimetransformpre_late koru_std/ctx.kz:57

~part finish koru_std/ctx.finish.kz

Koru Standard Library: the `finish` part of ctx — the clone drain and whole-program finish for `ctx:default`. Joined via `~part finish` in ctx.kz; merged into the ctx module at load. Recursive orig lookup for clone synthesis — the template decl and its impl flow may live inside a module_decl. Returns the decl, the impl flow, and the owning module's canonical path ("" = top level).