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

Channel

import std/channel

Koru Standard Library: Channels — bounded MPMC channels over proto elements.

channel.kz · 6 tors

Koru Standard Library: Channels — bounded MPMC channels over proto elements. · 63 more lines
Koru Standard Library: Channels — bounded MPMC channels over proto elements. std/channel:new(inbox, capacity: 256) { reading: Reading } // declare std/channel(inbox) // program-wide consumer join ! reading r |> handle(r) // competing consumer arm ! closed |> shutdown() // close arm (reserved word) std/channel:send(inbox, r) | ok |> .. | full |> .. | closed |> .. std/channel:send(inbox, reading: r) | .. // kind-labeled form (multi-kind) std/channel:recv(inbox) | some v |> .. | none |> .. | closed |> .. std/channel:close(inbox) | ok |> .. THE SHAPE (docs/CHANNEL.md, ruled 2026-09-24): the `{ }` body is a BRANCH TABLE — each `name: Proto` entry is one message kind: the arm word plus the proto its payload carries. Multi-kind is legal (`{ reading: Reading, alert: Alert }` → `! reading` + `! alert`); each kind gets its own ring — one firing carries one kind, and a value of a kind never queues behind another kind. `capacity:` is required, a power of two above zero; `capacity: 0` is the rendezvous spelling — deferred, refused with teaching. `std/channel(name)` is the bare-reference JOIN (the `default` tor, a [pre] rewrite to `consume` — the store `default`→`watch` pattern): `!` arms on it attach program-wide and are COLLECTED BY `new`, which splices them into the generated drain — consumers are statically enumerable, one value goes to one unit, join order. Arms under `channel:new` itself refuse. What the declaration emits into the channel's home module: - `pub const <Proto> = struct { ... }` per kind's proto — skipped when another consumer (std/list:new) already derived it. - `__koru_chan_<n>_<kind>_ring: MpmcRing(<Proto>, cap)` per kind, plus one `__koru_chan_<n>_closed` atomic — rings.kz carries no close bit; closed is channel semantics, not queue mechanics. - `__channel_send_<n>_<kind>` { value: Proto } | ok | full | closed — one send tor per kind. - `__channel_recv_<n>` {} | some Proto | none | closed — single-kind channels only (recv can't spell one payload type on a multi-kind channel; it refuses with teaching at the site). - `__channel_close_<n>` {} | ok — sets the bit, fires every `! closed` unit in join order. - `__channel_<n>_<kind>_<i>` / `__channel_<n>_closed_<i>` — one generated unit per `!` arm, the emitVerbUnit convention. - `<n>-step` / `<n>-live` / `<n>-wait` — the pump participant verbs, the same names a `! step` store exposes, so a channel joins a pump by name: std/pump(main) ! step |> inbox-step() ! live |> inbox-live() ! wait i |> inbox-wait(i: i) step: one drain pass — for each kind, each of that kind's consumer units attempts one dequeue in join order (competing: first pop wins the value); returns items moved. live: 0 once closed AND every kind's ring is drained. wait: `-> i128`, 1ms — a same-thread re-poll interest (a scalar IS a deadline); the cross-thread eventfd rung is deliberately unbuilt. `closed`-arm timing: the units fire inside `std/channel:close` — the transition point — so a channel never joined to a pump still runs them. Ordering law (same as pump/store): the declaration precedes its uses in document order — transforms run in source order and the chain steps find the channel by its emitted marker.

new

keywordcomptimetransform koru_std/channel.kz:545

default

keywordcomptimetransformpre koru_std/channel.kz:919

consume

keywordcomptimetransform koru_std/channel.kz:993

send

keywordcomptimetransform koru_std/channel.kz:1407

recv

keywordcomptimetransform koru_std/channel.kz:1421

close

keywordcomptimetransform koru_std/channel.kz:1435

~part custody koru_std/channel.custody.kz

Koru Standard Library: the `custody` part of channel — obligation transit. Joined via `~part custody` in channel.kz; merged into the channel module. Custody detection — the per-edge obligation contract (concepts/frag-custody-transit-is-an-edge-contract). A send of a value whose producer ISSUED it (`-> T<state!>` — the `!` suffix marks an issued obligation; `T<!state>` consumes, `T<state>` borrows) transits custody through the vessel. Resolution this rung is same-flow: the ident's `return_binding` producer. Anything unresolvable stays plain. The machinery is transform composition: `new` scans send sites (this part) and emits the `take`/`obligate` pair plus consumer units (the transit part); `send` injects the take under `| ok` alone; consumer units mint via obligate before the arm body.

~part transit koru_std/channel.transit.kz

Koru Standard Library: the `transit` part of channel — emission of the custody pair and the consumer units. Joined via `~part transit` in channel.kz; merged into the channel module. Detection lives in the custody part (which sends transit, under what state); this half emits the machinery that carries it: `take`/`obligate` per custodial kind, the `!`-arm units that mint via obligate, and the take node injected under a custodial send's `| ok`.

~part home koru_std/channel.home.kz

Channel home resolution — where a channel declaration or a chain-step flow lives, spelled for synthesized path qualifiers. Joined via `~part home` in channel.kz; merged into the channel module. The generic tree walks (moduleHome, containingFlow, findEventDecl) live in ast_functional — every comptime module needs them and .kz parts cannot share private fns. This file also declares the module's ast_functional import for that reason; channel.kz's `std`/`ast` are already module-wide.

~part leaves koru_std/channel.leaves.kz

Koru Standard Library: the `leaves` part of channel — proto leaf reading. Joined via `~part leaves` in channel.kz; merged into the channel module. A channel kind is a proto name; this part is everything the transform needs to read that name's LEAVES: the field list (`FieldPair`, `protoSourceText`/`protoFields`/`expandInto`), the Zig material each leaf lowers to (`zigFieldType`), and the owned-leaf split — `*mod:Type<state!>` spells a debt at a path, so composite kinds get a `take` param / arg per leaf (`takeFields`, `takeArgs`).

~part units koru_std/channel.units.kz

Koru Standard Library: the `units` part of channel — consumer-unit emission. Joined via `~part units` in channel.kz; merged into the channel module. Each `!`-arm of a consumer compiles to a callable void unit — an event_decl + impl pair on pump.kz's drained-unit convention. A custodial kind's unit takes a plain `__payload` and obligates it onto the arm's own binding as the first step, so `! <kind> v |> body` runs with `v` live — whole-value `<state!>` or per-leaf proto debts alike.