lume

05 — Vision: a language for the AI era that can build anything, from a kernel to a mind

This is the opinionated document. 01-survey.md says what history taught; this one says what to build and why, including the bets that could be wrong.


0. The thesis in one paragraph

Every mainstream language was designed for a world where humans write all the code and the computer only executes it. Both assumptions are now false. Most new code will be written with or by AI models; most interesting programs will contain models (neural networks, LLM calls, probabilistic reasoning); and the hardware those programs run on is no longer “a CPU” but a zoo of CPUs, GPUs, NPUs and FPGAs. A language designed today should take all three as givens. Nobody has done that yet — Mojo took the hardware part, DSPy/BAML took the LLM part, Rust took safety — and all of them sit inside or beside Python. Lume’s bet is that one coherent language can cover the whole stack: the boot sector, the kernel, the database, the business app, the training loop, the inference kernel and the agent that orchestrates them — and that being designed for AI authorship is the thing that makes the whole-stack ambition feasible for the first time.

1. Four audiences, one language

  1. The human programmer — needs readability, a small spec, great errors, fast feedback.
  2. The AI programmer (an LLM writing or editing Lume) — needs unambiguous syntax, local reasoning (you can understand a function without reading the whole program), machine-checkable intent (types, contracts, effects, tests) so its mistakes are caught by the compiler not the user, and a structured way to receive feedback (diagnostics as data).
  3. The machine — needs predictable layout, zero-cost abstraction, control over memory and time, and a path to every target (CPU, GPU, bare metal, WASM).
  4. The model inside the program — needs tensors, gradients, probability, and an integration with the type system so a model is a typed component, not a blob.

Every design decision below is scored against all four. That is the innovation: not any single feature, but refusing to sacrifice one audience for another.

2. Ten things no mainstream language does, that Lume does

2.1 Designed for AI authorship (the “AI-native” part that is not about tensors)

Most “AI languages” mean “languages for writing AI”. The first and bigger opportunity is a language written by AI, verified by the compiler, reviewed by the human. Concretely:

2.2 Models are typed values

type Classifier = model
    params:  Params           # a tree of tensors; serialisable; versioned
    forward: fn(x: tensor[f32, batch, 3, 224, 224]) -> tensor[f32, batch, 1000]

2.3 Accelerators are a target, not a foreign land

kernel fn saxpy(a: f32, x: tensor[f32, n], y: mut tensor[f32, n])
    for i in par 0..n          # data-parallel; compiler maps to threads/warps/lanes
        y[i] = a * x[i] + y[i]

2.4 Probability and knowledge are language constructs

fn coin(bias_prior: Beta) / {prob}
    let p = sample bias_prior
    observe flips ~ Bernoulli(p)
    return p

let posterior = infer coin(Beta(1, 1)) with mcmc(steps = 10_000)

2.5 LLM calls are typed functions with contracts

extern llm fn extract_invoice(text: str) -> Invoice / {net, llm}
    """Extract the invoice fields. Dates ISO-8601. Amounts as decimal."""
    ensures result.total == result.items.sum(.amount)

2.6 Data is native, persistent and typed

The dBase/Clipper/MUMPS inheritance, modernised:

2.7 Effects: one mechanism for safety, async, capability security and purity

fn f() -> T / {io, alloc, net, async, prob, gpu, unsafe, interrupt, realtime, llm} — inferred, shown at pub boundaries, enforced:

2.8 Memory: safe by default, three honest tiers, no religion

  1. Owned values + inferred borrows (Rust safety, Hylo ergonomics): the default; zero cost.
  2. Shared: rc[T]/arc[T]/cell[T] with literal syntax and good diagnostics; cycles detected statically where possible, weak otherwise.
  3. @gc regions: a tracing collector for a region/type (not the whole program) for the graph-shaped problems where ownership is the wrong tool (compilers, editors, GUI trees, symbolic AI). Kernels and kernels’ users never pay for it because it does not exist unless declared.

Plus explicit allocators (Zig) everywhere in std, so the same std.collections works in a kernel with a bump allocator and in a server with a general-purpose one.

2.9 From boot sector to browser with one toolchain

2.10 Small verified core, big friendly surface

3. What would make this “fantastic” rather than merely “complete”

Features are table stakes. These are the experience goals that decide whether people love it:

  1. Flow: edit → result in under 200 ms for the debug tier, always. Turbo Pascal in 1983 did it; we have no excuse.
  2. The compiler is a teacher: every error explains itself, names the concept, shows a fix, and links to the one page of the spec that matters. Measured: a new user should fix 90% of errors without a search engine.
  3. One tool, zero yak-shaving: lume new, lume run, lume test, lume fmt, lume doc, lume prove, lume bench, lume pkg, lume agent. No Makefiles, no CMake, no virtualenvs, no webpack, no Dockerfiles for dev. Reproducible by default (content-addressed store).
  4. Progressive depth: a 12-year-old writes a script on day one; the same file, with types and contracts added, becomes a verified kernel module. No cliffs, no “now rewrite it in C++”.
  5. Trust: no undefined behaviour, no null, no data races, no supply-chain surprises, no silent float money. A Lume program that compiles has a meaning.
  6. Longevity: editions, a stability promise, and a specification so that Lume code from 2026 compiles in 2056 — the COBOL/Fortran/Java virtue that fashionable languages forget.

4. The bets that could be wrong (and the fallback for each)

Bet Risk Fallback
Indentation syntax for a systems language Macro-heavy or generated code may prefer braces; copy-paste hazards Grammar accepts an explicit-brace form that the formatter normalises; both are the same AST
Region inference removes most lifetime annotations Inference may be slow or produce confusing errors on hard cases Fall back to Rust-style explicit annotations in those functions only; errors suggest them
Effects with inference stay ergonomic Effect rows can get noisy in higher-order code Effect aliases (/ {io} expands to a named set), inference hides them unless pub
MLIR as the main backend Heavy dependency, slow builds Cranelift tier for debug/REPL; LLVM-only build option; MLIR only for kernel/tensor paths at first
@gc regions won’t fragment the ecosystem Two memory models in one language has hurt D and Nim Regions are per-type and never cross a pub API without being visible in the type; std is GC-free
LLM calls as language features age badly Model APIs change monthly The core only knows “an extern function with schema-driven decoding and an effect”; providers are stdlib handlers, replaceable
The whole-stack ambition is too big Scope creep kills languages Phases (see roadmap): the core language + tooling must be excellent alone before model/kernel/llm ship; each is a macro library over the core, so they can lag without blocking

5. Name

“Lume” — light in Portuguese/Galician; short; .lume files; lumec compiler; lume tool. If a collision appears (there is a small JS library and a LaTeX package with the name), alternatives with the same feel: Lúmen, Faro (lighthouse), Ígnis, Aurea, Omega (the author’s brand). Decide before the first public release, not before.

6. Where to start (the first 90 days) — and how Lume becomes self-evolving

No Rust, no third language in the loop. The bootstrap strategy is the classic one, chosen so that Lume owns itself as early as possible:

Order of work:

  1. Freeze lume-core (the ~30-construct typed IR) and the Stage 0 interpreter in C.
  2. Parser + formatter for the surface syntax, with the JSON diagnostics protocol from day one — the AI-authorship workflow is tested on the compiler itself (an LLM writing Lume, the compiler correcting it) before any human ergonomics are polished.
  3. Type checker with inference, ADTs, traits, effects (inference only; no handlers yet).
  4. Ownership/borrow checker on the core IR.
  5. Native backend → binaries. At this point Lume replaces Go/Python scripts and lumec is written in Lume.
  6. Then, in order of leverage: table/query (the data story is Lume’s most visible differentiator), comptime + macros (unlocks everything else as libraries), tensors/grad (the AI story), freestanding + a toy kernel (the OS story), and lume evolve.