Programming Language

Nocter

A self-contained systems language built around simplicity, encapsulation, and foolproof design.

/releases/v0.47.0.md

Nocter v0.47.0 Release Notes

Nocter v0.47.0 makes asynchronous byte streams the canonical generic I/O surface. Unqualified Reader and Writer now describe executor-safe operations, while synchronous code uses the explicit BlockingReader and BlockingWriter names. Shared async defaults remove transport-level duplication without hiding readiness, timeout, cancellation, ownership, or failure behavior.

This release intentionally renames the previous synchronous interfaces. No compatibility aliases are retained.

Canonical Asynchronous Byte Contracts

Reader.read and Writer.write are asynchronous requirements:

pub interface Reader {
    pub async method &+self.read(buffer: &+[u8]): usize!
}

pub interface Writer {
    pub async method &+self.write(value: &[u8]): void!
}

Generic algorithms await those requirements directly. A caller can use one algorithm with an in-memory adapter, TcpStream, TlsStream, or an HTTP response body without selecting a second interface family or concrete collector.

One Set of Portable Defaults

The async interfaces own common whole-stream and text behavior once. Reader defaults collect all bytes, validate UTF-8, and read lines. Writer defaults write complete buffers and text, append line terminators, and flush. Implementations provide only their primitive progress operation unless they have a transport-specific policy.

Invalid read counts, zero progress, partial writes, end of stream, recoverable failure, allocation failure, and UTF-8 rejection have the same public meaning for every implementation. Cancellation drops the suspended computation and its logical wait without consuming a borrowed stream.

Explicit Synchronous I/O

Synchronous generic code now names its execution behavior:

  • BlockingReader owns synchronous read_blocking and its blocking defaults;
  • BlockingWriter owns synchronous write_blocking and its blocking defaults;
  • Reader and Writer never select a blocking operation merely because a concrete type also implements a blocking contract.

File, file buffers, TCP, TLS, HTTP response bodies, JSON generation, and public examples use the appropriate explicit contract. A synchronous witness cannot satisfy an async requirement by returning a future with a similar shape.

Transport-Specific Policy Stays Concrete

TCP and TLS implement both execution surfaces over one owned connection. HTTP Response exposes both reader contracts over its body cursor. Ordinary async collection uses the generic Reader defaults; timeout-bearing operations remain concrete because deadlines and transport progress are not properties of every byte stream.

HTTP framing, TLS authentication, readiness registration, per-operation deadlines, and close policy remain in their existing transport owners. The generic I/O layer does not infer them from a type name or hide them behind a universal stream implementation.

Editor and Integration Support

The asynchronous HTTP example defines one generic per-read deadline adapter and uses it with both server-side TCP and a client-side HTTP response. Native qualification covers required and default interface dispatch, multiple reads, partial progress, EOF, failure, cancellation, UTF-8 validation, and exact output.

Hover, completion, signature help, definition and implementation navigation, semantic tokens, and inlay hints consume the same checked interface contracts and frozen dispatch decisions as ordinary compilation. Compiler source and syntax snapshot identities were also hardened so independently parsed or edited generations cannot satisfy each other's internal ownership checks through equal local indexes.

Migration and Non-goals

Code that used the previous synchronous Reader or Writer interface must use BlockingReader or BlockingWriter. Async code uses the unqualified interfaces and awaits their methods. Concrete _blocking method names remain explicit.

v0.47.0 does not add asynchronous regular-file or directory operations, a blocking-worker pool, detached tasks, threads, parallel execution, generic datagram I/O, seek, vectored I/O, memory mapping, or effect-polymorphic interface methods. The supported distribution remains a self-contained arm64-darwin compiler and standard library.

Release Qualification

Release-content commit e191c63a881899e9e1df833184111d0ef4116026 passed the complete compiler, documentation, packaging, example, installed-home, LSP, immutability, and tamper gates. Two independent optimized builds produced byte-identical archives and recursively identical homes.

The retained nocter-v0.47.0-arm64-darwin.tar.gz archive is 8,962,525 bytes with SHA-256 eefbd8470cd08d77b96e8c24ba5cf6bae5acc588f0c71ed332d8c8290ab5498c. Its compiler SHA-256 is b068cb5e6a80c948cb6bc406fe9415250e05c43eb7b1c9713c0b62d05cda31ef, and its 276-file standard library has tree SHA-256 ace1a81aaa1d4224758cb15910db8dcdcdd6e67cc60a8d38c7873ff9d7e48562. Publication reused this retained archive without rebuilding it.