Albite

Albite v1.5

Albite v1.5 (released as Tungsten by Spinning Cat Studios).

Released 22 May 2026. Superseded by 2.0-alpha.

v1.5 was about closing the gap between “self-hosted compiler” and “language you would choose to write something in”. Every v1.0 known limitation was resolved, and the proof surface gained propositional equality and induction.

This page covers the user-facing changes. The full changelog, including compiler architecture and performance work, is in the repository.

Language

  • Early return — leave a function before its end, with bottom-type semantics. See Functions.
  • The ? operator — early return on error for Result and Option.
  • try blocks — build a Result without needing a function boundary.
  • let else — bind a refutable pattern with a diverging else branch.
  • if let, with chaining — if let Ok(x) = a && let Ok(y) = b { … }.
  • Nested constructor patterns — Cons(Pair(a, b), rest), and nested tuples inside constructors such as Ok((tok, cur)).
  • Named record constructors — Point { x: 0, y: 0 }.
  • Record spread — { ...base, field: new } functional update.
  • Generic type aliases — type ParseResult<T> = Result<(T, Cursor), ParseError>.
  • Import aliasing — use foo::Bar as Alias.

See Errors and optionality and Control flow and pattern matching.

Proofs

  • Propositional equality — the Eq<T, a, b> type with refl, plus the sym, trans, cong and subst combinators.
  • natind — the induction eliminator for naturals, with motive-driven type checking, and natrec for primitive recursion.
  • Motive type checking — eliminators infer and check motive types for dependent elimination.

See Induction over naturals.

Modules

  • Per-module elaboration — the flattening pass is gone; each module is elaborated on its own with proper cross-module resolution.
  • Visibility enforcement — per constructor, per field, and capping on pub use re-exports.

Tooling

  • albite test — discovery of test_* functions, with --filter, --module and --check-only.
  • Compile-time assertions — expect_type(expr, "T") and expect_error(expr, "E0001"), both checked during elaboration with no codegen.
  • Better diagnostics — multi-file spans, contextual hints, and error-cascade prevention so one failed body no longer invalidates every signature.

Compilation

  • Elaboration caching — warm-cache self-compile under 500 ms, down from roughly 32 minutes cold.
  • Parallel codegen — per-function codegen units compiled in process.
  • Static linking — a single binary, with no LD_LIBRARY_PATH needed.
  • Tail-call optimisation via musttail, removing the 64 MB stack trampoline.
  • Escape analysis — non-escaping closures and ADT values are stack allocated.
  • Deterministic IR — byte-identical .ll output across compiler generations.
  • Linux/x86_64 self-hosting, alongside ARM64 macOS.

Known issues

Three divergences were found while writing this documentation and are not yet fixed — early return and cross-module name resolution under the interpreter, and ? inside a try block at codegen. All three are detailed under Current limitations.