Roadmap
mu stays minimal, self-hostable, practical and predictable. The roadmap is a sequence of small, testable steps that keep the compiler, VM and documentation in lockstep.
The original phases have landed. What follows is where mu actually stands, and which directions are open from here.
North star
- Keep the grammar and builtin surface small — and shrink it where mu can carry the weight itself.
- Make compiler and VM behaviour explicit and testable.
- Keep the host self-contained while growing the stdlib in mu.
- Ensure every backend agrees on semantics.
Where mu is now
Each of these is checkable rather than asserted — the command that proves it follows the claim.
- Self-hosting.
selfhost/holds a lexer, parser, compiler, VM and native backend written in mu. Compiling it with itself reaches a byte-identical fixpoint, gcc-style, with no Go in the path, on the bootstrap targets that run the full chain today. →sh scripts/bootstrap.sh - Native compilation with no assembler or linker. The Go host targets
darwin/arm64,linux/amd64,linux/arm64, andlinux/riscv64; the self-hosted native backend targetsdarwin/arm64,linux/amd64, andlinux/riscv64. →mu -B -p linux/riscv64 -o hello hello.mu - Two frontends, identical bytecode. The Go and mu compilers emit the same
function bodies byte for byte.
→
sh scripts/frontend-diff.sh - One stdlib, four backends. The mu test suite runs on the Go VM, the Go
native backend, the self-hosted VM and self-hosted native binaries.
→
make test,sh scripts/native-test.sh,sh scripts/selfhost-vm-test.sh - Tooling via flags:
-check,-fmt,-test,-S,-c,-B,-p,-deps— one binary, no subcommands. →mu -check,mu -test ./lib - Exact decimals and an operator protocol.
3.14is a literal,0.1 + 0.2is0.3, and__opslets your own types define operators. Decimals are built entirely from that protocol — the language itself knows nothing about them. → the language tour - Macros as ordinary functions over first-class
CODEvalues, expanded on the build machine. → Macros - A shrinking host. Six builtins were rewritten in mu and removed: 33
callable builtins down to 27.
→
help() - Deterministic concurrency — cooperative tasks and channels with FIFO scheduling, plus scheduler-aware blocking I/O. → Concurrency
Where it could go next
Candidates, not commitments. The old blocker list is mostly closed: macro
hygiene, top-level macro.define ordering, formatter parity, ord/chr
Unicode behavior, string write-target protection, heap growth, Linux native FFI,
and concurrency across the execution paths are no longer roadmap items.
Backend and target coverage
- Keep the four execution paths in lockstep as features move. The conformance corpus is the contract: if one backend differs, the language contract is not finished for that behavior.
- Add
linux/arm64to the self-hosted native backend so its target list matches the Go backend’s practical Linux coverage. - Decide whether
darwin/amd64is worth carrying. Neither backend targets it today. - Continue narrowing FFI edges: Go VM FFI depends on cgo, and self-hosted native
linux/riscv64currently omits the directdlopen/dlsym/dlcallbuiltins.
Diagnostics and tooling
- Improve stack traces and source locations for VM and native failures.
- Keep
-fmt,-check,-deps, and-testboring: stable output, clear errors, and no data loss. - Grow editor tooling from the spec and grammar rather than by duplicating guesswork in extensions.
System libraries
- Keep expanding process and sockets helpers in mu, not in the host builtin table.
- Add deadlines/timeouts and Unix-socket helpers only when real programs need them.
- Prefer small stdlib modules with explicit imports over new ambient globals.
The host surface
The builtin table is at its floor. An audit of all 27 remaining builtins found nothing else worth moving into mu: what is left needs the kernel, raw memory, the loader, the scheduler, the runtime type tag, or a mutation mu cannot express. What remains is bookkeeping — a one-time compaction of the slots the relocated builtins left behind, which shifts a bytecode-level index and so needs its own flag day (#46).
Performance
Largely unexplored, and deliberately so — correctness and cross-backend parity came first. Compiler optimisations, VM speedups, and a memory model that does not surprise anyone under concurrency are all open ground.
Anti-goals
- A large “batteries included” stdlib in the core.
- A complex type system.
- Implicit async/await or promise-based concurrency.
Anti-goals are positions, not vows. “A macro system” sat on this list for most of mu’s life and came off it when a design arrived that did not require a second language: macros are ordinary mu functions over code values, and they expand before bytecode exists.
Learn more
For the authoritative roadmap and acceptance criteria, see docs/Roadmap.md.
Next steps
- Read the runtime guide for VM/native context.
- Explore the standard library to see how features land in mu.
- Start with the language tour if you’re new.