Misc — reference
The small modules that don’t need a page of their own: std::io,
std::promise, std::context, std::crypto, std::jwt, std::asset.
std::io
fun print(message: any) // console.log
fun panic(message: str) // abort with a message
fun assert(condition: bool, message: str) // panic when false
panic is for unreachable states (expected failures are Result). A
panic arm in a match diverges — the other arms decide the match’s
type. assert is the vilan test failure mechanism.
std::task
external struct Task<T>;
impl Task<type T> {
fun settle_all(tasks: List<Task<T>>): List<T> // async; implicitly awaited
fun race(tasks: List<Task<T>>): T // async; first settled wins
}
fun nursery<T>(body: (|Nursery| T) context ambient_nursery): T
external struct Nursery;
impl Nursery {
fun cancel(self) // abort the extent's signal
fun is_cancelled(self): bool // the compute-loop check
fun signal(self): CancelSignal // the raw host AbortSignal
}
resource struct OwnedNursery { nursery: Nursery }
impl OwnedNursery {
fun new(): OwnedNursery // a detached owner
fun enter<T>(&self, body: (|| T) context ambient_nursery): T // spawns inside → owned
fun cancel(&self) // early, idempotent
}
// `impl OwnedNursery with Drop` cancels the owned nursery at scope end.
fun ambient_signal(): Option<CancelSignal> // the enclosing nursery's, if any
Tasks only arise from spawning (async expr); see the
async tour. The handle is opaque and copying it
refers to the same task. Every task absorbs its own failure: a later
await receives it, and a task nobody awaits reports the error (with
its spawn origin) instead of crashing the program. Keep the task instead
of the results by spawning the settle_all itself:
let pending = async Task::settle_all(tasks);.
nursery(body) joins every task spawned in the body’s dynamic extent —
the body’s value passes through, the first-observed failure re-raises
with its spawn origin, and everything else is absorbed. cancel()
aborts the nursery’s signal; sleep and fetch carry the ambient
signal automatically, so in-flight IO in the extent rejects promptly,
and those rejections absorb as cancellation echoes. Task::race +
cancel() is the race idiom: first settled wins, the losers’ IO stops.
Spec: §7.7. ambient_signal() bridges host
APIs std doesn’t wrap.
OwnedNursery is the owner for background work no function-scoped
nursery can hold — a task whose lifetime is an object’s, not a call’s.
It is a resource: it has a single owner, moves, and is destroyed
deterministically. new() makes a detached owner; enter(body) runs
body with the owner’s nursery ambient, so every task spawned inside
registers with it — but, unlike nursery, enter does NOT join: it
returns as soon as the body settles, leaving the tasks running.
Dropping the owner (at scope end, or drop(owner)) cancels them, so
in-flight bridged IO aborts. Because the owner’s nursery is never joined
it runs detached: a child’s REAL failure reports to the console with
its spawn origin — as a free-floating task would — instead of being
absorbed for a join, and children do not cancel their siblings
(ownership is lifetime, not fate-sharing). Cancellation echoes, from the
owner’s cancel or drop, stay silent.
std::promise
external struct Promise<T>;
impl Promise<type T> {
fun all(promises: List<Promise<T>>): List<T> // async; implicitly awaited
}
The raw host promise, for direct host interop: an
[extern(new, "Promise")] constructor or a promise-returning host API
is typed Promise<T>, and await unwraps it exactly like a task. Code
that only spawns never sees this type.
std::context
Ambient values with dynamic extent — the machinery under owner_scope and
turn_scope:
impl Context<type T> {
fun new(): Context<T>
fun run<U>(self, value: T, body: || U): U // establish for the body's extent
fun get(self): T // read (compile error if possibly absent)
fun get_safe(self): Option<T> // read, absence as None
}
getis statically covered: the compiler proves every call path runs inside arun— an uncovered read is a compile error, not a runtimeNone.- Closures capture their contexts at creation; parameters declare
context needs with the
contextclause (functions & closures). - Async-safe by construction: a continuation sees the value captured at creation, across awaits and interleaved extents.
Define module-level contexts for app-wide ambients (a session identity on the server is the canonical use).
std::crypto
fun random_bytes(length: i32): Bytes // cryptographically secure
fun random_uuid(): str
fun equals_constant_time(a: Bytes, b: Bytes): bool // timing-safe compare
WebCrypto-backed (async where the host is). For password hashing on the
server, bind the host’s sync primitives as externs (the kolt pilot uses
node’s pbkdf2Sync) — candidates for std promotion.
std::jwt
HS512 JSON Web Tokens; claims are any Wire type:
async fun sign_hs512<C: Wire>(secret: Bytes, claims: C): str
async fun verify_hs512<C: Wire>(secret: Bytes, token: str): Option<C>
fun decode_claims<C: Wire>(segment: str): Option<C> // decode WITHOUT verifying
verify_hs512 checks the signature (constant-time) before yielding claims;
decode_claims is for non-security introspection only.
std::asset
fun emit(kind: str, line: str) // compile-time only: append to a build asset
Callable only from const evaluation — it’s how std::style writes the
CSS file (emit("css", rule)). A browser build with emissions produces
<entry>.css beside <entry>.js.