Nocter v0.41.0 Release Notes
Nocter v0.41.0 completes a structured asynchronous I/O foundation. An ordinary program can create a lazy asynchronous computation, await timers and TCP readiness without blocking the executor, compose two owned computations, and rely on deterministic cancellation and cleanup. The only implemented host and native target remains arm64-darwin.
Asynchronous Values
Asynchronous production is written as a result type:
func fetch(url: Url): async String!
async T is a lazy, single-use owning computation. A call constructs the computation without running its body, await consumes it and produces T, and destroying an unfinished computation cancels it. async T! means async (T!); an immediate fallible operation that returns a computation is written (async T)!.
Suspension and thread blocking are independent facts. Existing synchronous APIs remain synchronous, and creating an async value does not start a hidden process-global executor.
Checked Ownership and Generated State Machines
The checker decides deferred execution, suspension legality, captured storage, retained borrows, and ordered cleanup once. MIR turns each reachable deferred callable into an explicit lifecycle with constructor, resume, cancel, and completed-output consumption transitions. Machine freezes frame placement and ABI facts before ARM64 emission.
Each computation owns one stable allocation-backed frame. Cancellation removes pending reactor registrations before destroying initialized frame values, stale events cannot resume a replacement task, and completed output transfers through a typed consume entry without exposing frame layout.
Executor and Darwin Readiness
Generated programs use an owned single-threaded executor and a kqueue-backed Darwin reactor. Runnable order is deterministic, descriptor and timer interests are registered atomically, and stable identities plus generations reject stale native events. The reactor exposes logical readiness only; it does not inspect task or frame representation.
The initial executor is explicit and single-threaded. This release does not add detached tasks, work stealing, a hidden blocking pool, or a Send/Sync-style cross-thread type system.
Async Time, TCP, and Structured Join
The standard library adds asynchronous sleeping, numeric and host TCP connection, listener acceptance, stream reads and complete writes, and timeout variants. Timed operations publish readiness and one monotonic deadline as a single wait set, so either outcome consumes the complete registration. Host connection resolves immediately, then owns and tries its candidate list in order inside the lazy computation.
task.join composes two heterogeneous owned computations. It preserves both outputs, combines arbitrary child wait sets, and cancels both children if the unconsumed join is destroyed. Nested joins provide bounded structured concurrency without detached lifetime or global scheduler state.
Public loopback coverage exercises concurrent connect and accept, joined write and read, partial I/O, backpressure, peer closure, timeouts, candidate fallback, and deterministic cleanup.
Examples and Tooling
The async-loopback package demonstrates public structured TCP concurrency. Hover, completion, signature help, definition, references, rename, semantic tokens, and inlay hints consume the same checked async representation used by compilation. The language server does not parse a second async language or inspect generated frame layout.
Compatibility and Non-goals
v0.41.0 does not add TLS or HTTPS transport, foreign callback ABIs, detached background tasks, multiple executor threads, asynchronous filesystem or subprocess semantics, a hidden blocking thread pool, public nonblocking descriptor manipulation, HTTP/2, HTTP/3, WebSocket, or another native target.
Release Qualification
Release-content commit d63f749f83847bf445112b49e94173b315233ee2 passed two independent complete compiler gates, the explicit public-HTTPS dependency-acquisition test, and two independent optimized package builds. The resulting archives and installed homes were identical. Fresh extraction passed the installed CLI, compilation of every public example, selected exact process contracts, native execution, framed LSP analysis, installed-home immutability, and compiler and standard-library tamper rejection. Both complete compiler gates independently executed every registered public example and its process contract.
The nocter-v0.41.0-arm64-darwin.tar.gz release is the exact retained qualified archive. It is 8,824,423 bytes with SHA-256 8d8f3cc77236c9fc900a08baad58565f5198a77c0c97da92385d3a1e22ac8fe0; publication did not rebuild it.