Nexium

A language complete enough to build everything in, that is also the best thing to adopt for one piece of something else.

Nexium compiles to native code through C, has automatic reference counting without a tracing collector, a machine-checked effect system that says whether a function allocates, blocks, or can panic, and a compiler that turns one source tree into a C library, a Python wheel, a Rust crate, an npm package, or a command line tool. The compiler is written in Nexium and builds itself from the C it emits.

The Topo

The route up the mountain, one pitch at a time: install, hello world, the REPL, a calculator, ownership, effects, a GUI, a neural network, shipping a library. Every program in it is run by the test suite.

The language reference

Every construct the compiler implements, with the rules for types, ownership, effects, binary patterns, compile time and C interop.

The standard library

Every module and function, generated from the doc comments in std/.

The specification

What Nexium promises: the document the conformance suite is written against, and what a version number means (stability, platforms).

Install#

Windows: the installer from the latest release installs nx, a bundled Zig toolchain, the standard library, the examples and the VS Code extension.

macOS and Linux:

curl -fsSL https://raw.githubusercontent.com/Londopy/nexium/main/installers/install.sh | sh

From source, with nothing but a C compiler (Zig on the PATH, or cc on macOS):

git clone https://github.com/Londopy/nexium
cd nexium
sh bootstrap/build.sh

The compiler is nx-out/bootstrap/nx2. More ways to install.

One file, every target#

/// A hash of the bytes, the FNV-1a way.
fn checksum(data: []u8) -> u32 export(c) {
    var h: u32 = 2166136261
    for b in data {
        h ^= b as u32
        h *%= 16777619
    }
    return h
}

artifact cabi   { name = "hasher" }
artifact python { name = "hasher" }
artifact node   { name = "hasher" }
$ nx ship hasher.nx
  hasher.h  hasher.dll  hasher.lib          # C, from the same source
  python/hasher/  hasher-1.0-*.whl          # pip install
  node/                                     # npm install

export(c) puts a function on the boundary. Because the checker proved checksum cannot panic, it gets its natural C signature; a function that could panic returns a status and the host gets an error instead of an abort. Embedding has the whole story.

What it feels like#

topo/code/centroid.nx
import std.json

struct Point derive(Eq) { x: f64, y: f64 }

fn centroid(points: []Point) -> ?Point {
    if points.len == 0 { return null }
    var sx = 0.0
    var sy = 0.0
    for p in points { sx += p.x; sy += p.y }
    let n = points.len as f64
    return Point{ .x = sx / n, .y = sy / n }
}

fn main() -> !void {
    let doc = try json.parse("[[0, 0], [4, 0], [4, 4], [0, 4]]")
    var points = List(Point).new()
    for i in 0..json.len(&doc) {
        let item = json.at(&doc, i) orelse continue
        let x = json.as_num(json.at(item, 0) orelse continue) orelse continue
        let y = json.as_num(json.at(item, 1) orelse continue) orelse continue
        points.append(Point{ .x = x, .y = y })
    }
    if let c = centroid(points[..]) { println("centroid ({}, {})", .{c.x, c.y}) }
}

The tools in the box#

nx build, run, test, check, fmt, doc, repl, lsp, ship, size, leaks, effects, audit, refcounts, doctor: one binary, no dependencies beyond a C compiler. The language server is nx lsp, and the repository's editors/ has it wired into VS Code, Vim, Neovim, Helix, Zed, Emacs, Kate, JetBrains, Sublime Text, Notepad++ and nano (the install guide has the one-liners).

Where things are#