Make programming sharp again.
Documentation · Quick start · Reference for AI assistants · Changelog · Suflae
RazorForge (.rf) is a natively compiled language built around precision: in what a program means,
in how it fails, and in the numbers it computes. It is meant for application work where you want
native code and predictable memory behavior: command-line tools, services, games, and data and
numeric tools. It is not a kernel or bare-metal language; programs link against a runtime library,
and there is no freestanding mode.
import IO/Console
entity Resource
tag: S64
routine consume(r: Resource)
show(f"consuming tag={r.tag}")
return
# r is destroyed here, exactly once
routine parse_digit!(c: Character) -> S64
unless "0123456789" have c
absent # fail without an error object
return S64(from_text: Text(from: c))
routine start()
var b = Resource(tag: 7)
consume(r: steal b) # ownership moves; using `b` afterwards is a build error
var d = try parse_digit(c: 'x') # `try` recovers the failure as Maybe[S64]
when d
is None => show("not a digit")
else n => show(f"digit {n}")
show(200u8 +^ 100u8) # clamping add: 255
return
Early alpha. The builder, runtime, and standard library work, and every commit passes about 1,500 unit tests and 240+ end-to-end programs (RazorForge and Suflae) on Windows, Linux, and macOS in CI. APIs will still change between releases, and you will find bugs.
Single ownership, no borrow checker. Containment is ownership. An entity has one owner, every
transfer is marked with steal, and cleanup runs deterministically at scope exit. To use an entity
you don't own, you take a scope-bound access token (view() / modify()), which needs no lifetime
syntax and cannot outlive the call or using block it appears in. When you want sharing, you opt
into reference counting with Retained[T], Guarded[T, P], or the weak Tracked[T] /
Witnessed[T].
Failure is loud by default, and recovery takes one keyword. A routine that can throw or go
absent carries ! on its declaration, never at its call sites. A bare call that fails crashes the
program with a message and a stack trace (exit status 82). To recover, put a keyword in front of the
call: try gives Maybe[T], grab gives Check[T] (which keeps the error), and lookup gives
Lookup[T]. There are no exceptions to declare or catch.
Numbers mean what they say. + - * are checked and crash on overflow; wrapping (+%) and
clamping (+^) are separate operators you choose. Integers go from S8/U8 to S256/U256, and
next to the binary floats B16–B128 sit decimal floats D32/D64/D128 and arbitrary-precision
Integer and Decimal. The float math library is correctly rounded, and a float prints as
the shortest text that reads back as the same value.
Markers go where a danger is silent. Ownership transfers are marked (steal), overflow behavior
is chosen per operator, and the few operations that can actually break memory safety live in
danger blocks. Everything else stays quiet: no lifetime annotations, no unsafe around ordinary
code.
Calls read on their own. Multi-parameter calls name their arguments (gcd(a: 252, b: 105)), an
ignored Bool result takes an explicit discard, and blocks are indentation, four spaces each.
Download the package for your platform from the releases page:
| Platform | File |
|---|---|
| Windows x64 | razorforge-v<version>-win-x64.zip |
| Linux x64 | razorforge-v<version>-linux-x64.tar.gz |
| macOS (Apple Silicon) | razorforge-v<version>-osx-arm64.tar.gz |
The package is self-contained: the builder, the standard library, the runtime, and the LLVM toolchain are all inside it. Unpack it anywhere and run the installer from that folder:
:: Windows: adds the folder to your user PATH
install.cmd# Linux / macOS: links the commands into ~/.local/bin
./install.shOpen a new terminal and check that it works:
razorforge versionThe same package installs Suflae too (suflae). Short aliases rf and sf work as well.
Linux: linking needs the C library's development files. Most machines have them; otherwise install
libc6-dev(Debian/Ubuntu) orglibc-devel(Fedora) once.macOS: linking uses Apple's Command Line Tools; run
xcode-select --installonce if you have never built anything on this Mac. This alpha is not notarized, andinstall.shclears the Gatekeeper quarantine on the unpacked folder for you.
# hello.rf
import IO/Console
routine start()
show("Hello from RazorForge!")
return
razorforge run hello.rfrun builds a native executable and runs it. razorforge build hello.rf stops after
building and leaves hello.exe next to the source.
Every routine ends with an explicit return; scope teardown is anchored there. A single-file
program may also skip routine start() and put its statements at the top level (script mode), and
module is optional: without it, the module path comes from the file's location.
RazorForge is not in any model's training data yet, so assistants tend to guess Rust- or
Python-flavored syntax that does not build. Point yours at
RAZORFORGE-FOR-AI.md, which also ships in every release package. It is a
compact list of where those guesses go wrong, with pointers to the CI-verified programs in
tests/Fixtures/Stdlib/.
razorforge buildandrun [entry-file] Build, link, and run
razorforge build [entry-file] Build a native executable for this OS (no run)
razorforge check [entry-file] Type-check only
razorforge codegen [entry-file] [out.ll] Stop at LLVM IR
razorforge parse <source-file> Parse and show an AST summary
razorforge tokenize <source-file> Show the tokens
razorforge validate-stdlib [language] Check the standard library's routine bodies
razorforge --lsp Run the language server over stdio
razorforge help | version
There are no build flags. All build configuration lives in the [target] section of a
config.toml manifest:
[package]
name = "my-app"
[target]
executable = "MainModule" # entry module (by module path, not file path)
library = ["../shared-utils"] # directories whose modules join the import search space
mode = "debug" # debug -O0 | release -O2 | release-time -O3 | release-space -OsWith no entry file, the command looks for config.toml in the current directory and its parents,
so cd into a project and run razorforge buildandrun.
- Builder pipeline: tokenizing, parsing, name and type resolution, desugaring, semantic
analysis, type-aware lowering, monomorphization, LLVM IR, and a native executable. Only code
reachable from
start()is built. Diagnostics readerror[RF-S###]: file:line:col: messagewith a source excerpt. - Memory model: single-ownership entities with deterministic
destroy,stealtransfers, scope-bound access tokens, theRetained/Guarded/Tracked/Witnessedreference-counted wrappers, anddangerblocks. - Error handling: failable routines (
throw/absent), thetry/grab/lookuprecovery keywords, andwhenpattern matching with exhaustiveness checks. - Numerics:
S8–S256,U8–U256,B16–B128(plusBF16for storage),D32/D64/D128, arbitrary-precisionInteger/Decimal, complexC64/C128/C256, quaternions, vectors, and SIMDVector[T, N], with checked, wrapping, and clamping arithmetic. - Collections:
List,Dict,Set,CircularList,BitList,PriorityQueue, the sorted collections,SplitList(struct of arrays), fixed-sizeArray[T, N], and lazy iterator adapters (select,where,zip,enumerate, …). Changing a collection while aneachloop walks it is a build error, including when the change is hidden behind a call. - Text: UTF-32
Text, f-strings,Byteswith UTF-8 helpers, and range slicing (text[a til b]). - Generics and protocols: type parameters with protocol constraints (
needs T obeys P), const generics (Array[T, N]), associated types. Everything monomorphizes; there is no runtime dispatch. - Concurrency: stackful coroutines (
suspended routine) and OS threads (threaded routine) behind oneAgent[T]handle,gather/race, typed channels with backpressure, async file I/O, and OS signal handlers. Async networking is not implemented yet. - Interop and build: realm-qualified
C::foreign routines and linking against C libraries, file-level conditional compilation (@target), and buildtime reflection (expand). - Tooling: a language server (diagnostics, hover, go-to-definition, rename, completion, inlay
hints, …), with setup scripts for VS Code (
setup-vscode) and a Rider plugin (rider-plugin/).
| Platform | Status |
|---|---|
| Windows x86-64 | Working, tested in CI on every commit |
| Linux x86-64 | Working, tested in CI on every commit |
| macOS ARM64 (Apple Silicon) | Working, tested in CI on every commit |
| Linux ARM64, macOS x86-64 | Target definitions exist, not tested |
On x86-64, programs target x86-64-v3 (Intel Haswell 2013+, AMD Excavator 2015+, every Ryzen), because the correctly rounded float math relies on hardware FMA. CPUs without AVX2 and FMA, including low-end Pentium, Celeron, and Atom parts, cannot run the output.
Suflae (.sf) is RazorForge's sibling. It shares the
grammar, the standard library, and the loud failures, and hides the ownership machinery: its
entities are shared reference-counted handles with a cycle collector, bare numbers are exact
Integer and Decimal, and it has thread-safe module globals. A .sf file can import .rf
modules, so one program can mix the two. Pick RazorForge when you want control over ownership and
widths, Suflae when you would rather not think about either.
The documentation lives at razorforge.lumi-dev.xyz:
- Hello World · Data Types · Pattern Matching
- Memory Model · Error Handling · Danger Blocks
- Collections · Numeric Types · Generics · Protocols
- C Subsystem · Build System · Design Philosophy
The programs in tests/Fixtures/Stdlib/ run on every commit and are
diffed against their .expected.txt output, so they double as working examples for nearly every
language feature and standard library API.
RazorForge/
├── src/ # The RazorForge front end: lexer, language rules, `razorforge` command line
├── Standard/ # The standard library (.rf), used by RazorForge and Suflae builds
├── tests/ # RazorForge.Tests: unit tests and end-to-end fixtures
│ └── Fixtures/Stdlib/ # programs with expected output
├── scripts/ # Packaging and maintenance scripts
├── rider-plugin/ # Rider plugin
├── RazorForge.tmbundle/ # TextMate grammar
├── RAZORFORGE-FOR-AI.md # Reference for AI assistants
└── CHANGELOG.md # Release notes for RazorForge and Suflae
The builder itself (parser, analysis, lowering, LLVM emission) is Anvila, and the shared library under the standard library is Ingrid.
Shipped (latest release: RazorForge 0.4.0)
- Native builds on Windows and Linux x86-64 and macOS ARM64, with prebuilt packages
- Ownership model, failable routines with recovery keywords, generics, collections, 256-bit integers, decimal and 128-bit floats
- Coroutines and threads behind
Agent[T], channels, async file I/O, signals - Language server with VS Code and Rider integration
Next
- A fast edit-and-rerun loop
- Async networking (TCP, then HTTP)
- Linux ARM64
- Package management
Later
- Native debug info (DWARF / PDB)
- A WASM backend
- A self-hosting builder
You only need this to work on the builder or the standard library. RazorForge is built from five repositories checked out side by side: the builder core (Anvila), the shared library (Ingrid), the two language front ends (this repository and Suflae), and Tessera, whose builder compiles part of the native runtime.
You need the .NET 10 SDK, LLVM 22 (clang and opt on PATH), CMake 3.20+, and Ninja on Windows.
mkdir LumiFoundry && cd LumiFoundry
git clone https://github.com/dj-lumiere/Anvila.git
git clone https://github.com/dj-lumiere/Ingrid.git
git clone https://github.com/dj-lumiere/RazorForge.git
git clone https://github.com/dj-lumiere/Suflae.git
git clone https://github.com/dj-lumiere/Tessera.git
dotnet build RazorForge/RazorForge.csproj # also builds the native runtime
dotnet test RazorForge/tests/RazorForge.Tests.csproj # optionalThe built command is RazorForge/bin/Debug/net10.0/RazorForge (RazorForge.exe on Windows).
Bug reports, feature suggestions, documentation fixes, and code are all welcome. A good start is to
build from source, run the tests, and read a few programs in tests/Fixtures/Stdlib/. Report bugs
at github.com/dj-lumiere/RazorForge/issues.
MIT; see LICENSE. Third-party components are listed in
THIRD-PARTY-NOTICES.md.