This library is in flux. APIs may change without notice. Generated from source with koruc 0.1.7 on 9/16/2026.
Refine
~import std/refineKoru Standard Library: Refine — value-level constraints on declared fields
refine.k · 2 tors
Koru Standard Library: Refine — value-level constraints on declared fields · 41 more lines
Koru Standard Library: Refine — value-level constraints on declared fields
`std/refine(Name) { name: type & constraint… }` — a definition surface for
constraints on ABSTRACTS: it never touches a value, only meets bounds onto
a declaration another module made. The `&`-atoms meet per field name,
order-independently; a meet that lands empty is a loud KORU205 refusal,
never a last-wins override.
SURFACE:
std/refine(Server) {
port: i64 & >1024 & <=65535
}
meets the `std/proto(Server)` declaration — refined fields must exist
there on one agreed base. The meet is name-keyed, total, confluent:
`std/refine` blocks in any module fold onto one facet that lands as a
typed `Item.facet_decl` — consumers match the node, never comment text.
LAYERING — the point of a separate module: a bound can arrive apart
from the declaration. A library declares `std/proto(Server)` plainly;
a downstream module writes `std/refine(lib/home:Server) { port: i64 &
>1024 }` — `home:Name` rides the named-arg channel (proto's own
`app/alpha:Health` convention), addressing the type by home while the
facet meets the declaration program-wide. Definition is import-scoped;
the constraint rides the type, so enforcement is type-global.
ENFORCEMENT IS THE CONSUMER'S: refine emits data, never a check.
`std/store` insert, `std/json` decode, `std/list:push` — each reads the
facet at its own boundary and decides. An unconsumed facet is
enumerable documentation, not a hole.
v0 ATOMS: `>N` `>=N` `<N` `<=N` `==N` over integer literals, plus the
`clamp(lo, hi)` normalizer — on integer scalar bases, raw (`i64`) or
named through a terminal (`Port`). Disjunction (`*a | b`) is next.
NOTE: `.k` files carry no host lines, so host types are spelled through
`std/compiler:` aliases (Program, Item, Source, Allocator); the
transform's own proc takes `std` inside its body and uses
`koru_allocator()` — the canonical accessor emitted into every module
(emitter_helpers.zig), riding the Debug leak counter.
The explainer (`koruc <file> explain`) reports the met facet; the impl
is refine.explain.kz. @retain: the generated gather invokes it.
~[comptime|explainer] pub tor explain-refine {
program: std/compiler:*const Program,
allocator: std/compiler:Allocator
} -> ExplainReport~[comptime|transform|pre] pub tor default {
expr: Expression,
source: Source,
item: std/compiler:*const Item,
program: std/compiler:*const Program,
reporter: std/compiler:*ErrorReporter
} -> SiteResult