View on GitHub

Nexus Language

A LLM-friendly language

Design

Nexus is built on one observation: LLMs are strong at literal program constructs but weak at contextual ones. Garbage collection, implicit conversions, ambient I/O, continuation-based control flow – these contextual mechanisms are where LLM-generated code breaks and where human review fails. Nexus replaces each with a syntactically explicit alternative.

Literal vs Contextual

Contextual (eliminated) Literal (Nexus alternative)
Implicit resource cleanup (GC, finalizers) % linear types – consumed exactly once
Hidden aliasing & borrow – explicit read-only view
Ambient I/O require { PermNet } – declared capability
Implicit control transfer (continuations) try/catch – traditional unwind semantics
Positional arguments add(a: 1, b: 2) – mandatory labeled arguments
Brace-matching (off-by-one) do ... end – keyword-terminated blocks
Implicit scope termination if ... then ... end, match ... do ... end

The principle is simple: if a construct requires looking elsewhere to understand what happens here, replace it with something that doesn’t.

Why Coeffects, Not Effects

Most effect system research focuses on algebraic effects – functions perform effect operations, and handlers intercept them using delimited continuations. The handler decides whether and how to resume the suspended computation. This is powerful but fundamentally contextual: the call site Logger.info(msg: x) tells you nothing about control flow. The handler could resume, abort, restart, or run the continuation multiple times.

Nexus rejects continuations entirely. Instead:

port Logger do
    fn info(msg: string) -> unit
end

let console_logger = handler Logger require { Console } do
    fn info(msg: string) -> unit do
        Console.println(val: "[INFO] " ++ msg)
        return ()
    end
end

let main = fn () -> unit require { PermConsole } do
    inject stdio.system_handler do
        inject console_logger do
            Logger.info(msg: "starting")
        end
    end
    return ()
end

The tradeoff is explicit: less expressive handlers in exchange for every call site meaning exactly what it says.

Linear Types as Literal Resource Tracking

Garbage collectors and finalizers are contextual – resources disappear “sometime later” through an invisible mechanism. Nexus makes resource lifecycle visible in syntax with the % sigil:

let %h = Fs.open_read(path: path)       // acquire
let %r = Fs.read(handle: %h)            // consume %h, get new handle back
match %r do
    case { content: c, handle: %h2 } ->
        Fs.close(handle: %h2)           // release
end

The compiler enforces exactly-once consumption. Fail to consume, consume twice, or discard with _ – rejected at compile time. No GC, no finalizers, no implicit drop.

Borrowing as Explicit Aliasing

Hidden aliasing is a major source of bugs in both human and LLM-generated code. The & sigil makes every alias visible:

let server = Net.listen(addr: addr)
let req = Net.accept(server: &server)    // &server: borrow, not consume
let method = request_method(req: &req)   // &req: borrow, not consume
let _ = Net.respond(req: req, ...)       // consume req
Net.stop(server: server)                 // consume server

Every read-without-consuming is syntactically marked. No hidden reference counting, no shared pointers, no implicit copies.

Labeled Arguments and Keyword Blocks

Positional arguments require looking at the function signature to know what each argument means. Brace-delimited blocks require counting braces to find boundaries. Nexus eliminates both:

// Every argument is self-documenting
let result = request_with_body(
    method: "POST",
    url: "https://api.example.com",
    headers: headers,
    body: payload
)

// Every block has an unambiguous terminator
if condition then
    // ...
end

Capability-Based Security

Ambient authority – where any function can read files, make network requests, or access the clock – is deeply contextual. The require clause makes the security surface visible at every function boundary:

let main = fn () -> unit require { PermNet, PermConsole } do
    inject net_handler, stdio_handler do
        let body = Net.get(url: "https://example.com")
        Console.println(val: body)
    end
    return ()
end

require { PermNet, PermConsole } is checked at compile time and enforced at the WASI runtime level. A function cannot perform network I/O unless it declares PermNet and a handler satisfying Net is injected. See WASM and WASI for the permission-to-capability mapping.