mach

A systems programming language with no hidden behavior.

One binary compiles, links, tests, and cross-compiles it. There is nothing else to install.

Installs the latest release to ~/.local/bin.

On Linux:

curl -fsSL https://machlang.org/install.sh | sh

On Windows, run it in PowerShell:

irm https://machlang.org/install.ps1 | iex

Run it in PowerShell.

On macOS (Apple Silicon):

curl -fsSL https://machlang.org/install.sh | sh
main.mach

Why mach?

Every cost is visible. No garbage collector, no exceptions, no hidden allocation, and no runtime that starts before your code does. What the language does for you, it does at compile time - where you can read it. Mach compiles itself: the binary you download was built by the release before it.

Discriminated values with tag and sel

Mach defines discriminated values with tag, where an explicit discriminator integer fixes the storage width and each case holds a single payload or none. Reading a payload requires a compile-time lexical guard: sel tests the active case, and only guarded branches can read the value.

Explicit Discriminators

Every tag specifies its underlying integer type from u8 through u64. Storage layout and discriminator width are never hidden.

Lexical Payload Guards

Payload access is enforced at compile time. sel r.case tests the variant, and reading r.case is permitted only inside the guarded branch or after an exiting error check.

No Pattern Matcher Runtime

Tag dispatch uses ordinary control flow with zero runtime overhead. There is no heavy pattern matching machinery or hidden allocations.

reply.mach
pub tag Reply: u8 {
    empty;
    value: i64;
}

fun handle(r: Reply) i64 {
    # sel tests the active case and opens a lexical guard
    if (sel r.value) {
        ret r.value;
    }

    # unhandled branches cannot read r.value
    ret 0;
}

Cross-compilation is a manifest entry.

The binary that builds for your machine builds for every platform you declare - hosted operating systems and bare metal alike. No cross-toolchain to install, no sysroot to assemble, no external linker: mach emits the objects and links them itself. Add a [target] and build.

  • linuxx86_64 / linux / sysv64
  • windowsx86_64 / windows / win64
  • freestandingx86_64 / freestanding / sysv64
  • linux-arm64aarch64 / linux / aapcs64
  • macosaarch64 / darwin / aapcs64
  • macos-x86_64x86_64 / darwin / sysv64
  • linux-riscv64riscv64 / linux / lp64d
  • riscv32riscv32 / freestanding / ilp32
  • gpuspirv / freestanding / spirv
mach.toml
$ mach build . --target linux
# linked -> out/linux/bin/app
[target.linux]
isa = "x86_64"
os  = "linux"
abi = "sysv64"

Get Started

From nothing to a running binary: one toolchain, no external linker, no build system to configure.

~
$ curl -fsSL https://machlang.org/install.sh | sh
# verifies the download, installs to ~/.local/bin
$ mach init my-app
$ cd my-app
$ mach dep pull .
# vendors dependencies into dep/
$ mach build .
# one binary builds and links, with no external linker
$ mach run .
Hello, World!

Next: read the documentation (a pamphlet, not a bible), or start from mach-sieve (a standalone starting point).

Join the Discord