ML types.
Effects as capabilities.
Actors, compiled native.
March is a statically typed functional language for programs built from actors. It takes message passing and supervision from the BEAM and algebraic data types from ML, and compiles the result to a native binary through LLVM. Memory is managed by Perceus reference counting with in-place reuse, so there is no garbage collector and no pauses, and functional code runs at Rust-like speed.
What makes March different
Safety is the compiler's job, not the test suite's.
Side effects are part of the type: a module declares the
capabilities it needs, so what any piece of
code can touch is visible in its signature, bounded by what main was granted, and
auditable across every dependency you pull in.
Linear types make a resource that is used out
of order, twice, or never a compile error.
Refinement types reject a value a function
cannot accept before it runs. A message protocol is checked on both sides, a crashed actor is
restarted the way you declared, and a running node
takes new code without a restart.
Capabilities
The whole program is bounded by main
main's capability parameter is the program's grant. Everything it reaches has to fit under it: every helper, every stdlib call, every dependency. Reach past it and the build fails, naming the chain that got there.
Three layers, one function
What, in what order, with what values
Capabilities say what resources code may touch. Linear types and typestate say how many times, and in what order, a resource is used. Refinement types say with what values a function may be called. They are independent, they compose on the same function, and all three fire at compile time.
Protocols
Typed conversations, two parties or twenty
Write the conversation once. Each role gets a typed module, so a send out of turn, a second receive, or a role that stops halfway does not compile; a runner connects the roles over the network, each its own program on its own machine.
Hot deploy
New code into a running node, gated by what it may do
forge deploy hot ships only the functions that changed; actors keep their state and migrate it in place. A patch that reaches for authority the running version did not have stops until you grant it by name, and the node's own policy can still refuse it.
Concurrency
Actor model, typed and isolated
Share-nothing message-passing actors with supervision trees. Accidental shared mutable state is a compile error, not a runtime bug.
Performance
Zero-allocation recursive transforms
FBIP rewrites uniquely-owned data in place, so transforms like this allocate nothing on the reuse path. The functional-style rewrite is automatic; no unsafe code required.
See benchmarks →
Benchmark
tree-transform(depth=20, 100 passes)
After pass 1, March allocates nothing — every node rewritten in-place. 7.5× faster than OCaml. 19× faster than Rust. Apple M-series, --opt 2.
| Language | Median | Allocs/pass |
|---|---|---|
| Elixir (BEAM) | 2580 ms | 2M |
| OCaml (ocamlopt) | 3825 ms | 2M |
| Rust (rustc -O) | 9977 ms | 2M |
| March (FBIP) | 513 ms | 0 ✓ |
← Back
Try March
See how March feels to write.
Full playground — no install needed ↗Quick Start
Get started in minutes
One command installs on macOS and Linux.