Skip to content
chrispaig3Public

About

The Functional Systems Language

Resources

Contributing

Security policy

Stars

16 stars

Watchers

0 watching

Forks

Repository files navigation

Axiom

GitHub CI

Axiom — High-level thinking. Native-level control.

The functional systems language.

High-level thinking, native-level control.

Axiom lets you model your ideas with algebraic data types and exhaustive pattern matching, check side effects at compile time, and ship a native executable with no VM, no garbage collector and no calls into the C library.

  • Ship the binary. That's it. Programs compile through LLVM to a native executable that carries its own allocator and talks to the kernel directly.
  • Make side effects explicit. The compiler infers effects, requires functions that perform I/O to say so, and checks promises like restrict(no-io).
  • Find the problem. Keep moving. Every error has a precise location, a stable code, often a fix your editor can apply, and a full explanation behind axiom explain.
  • Built for you and your agents. The syntax is uniform S-expressions, and the compiler can describe errors and symbols in a compact machine-readable form, so tools see the same facts you do.
  • Read the compiler, in Axiom. The compiler is written in Axiom: over 136,000 lines of it. A clean checkout rebuilds it from committed LLVM IR, and the build stops unless two generations come out byte-identical.
  • Bring Rust along. Declare Rust functions in an extern block, and axiom build --crate builds and links the crate for you.

Axiom is young. The core language is complete, the standard library, FFI and editor support are functional, and macros are partial. There is no package index and no green threads yet. What's ready today lists every feature with the test behind it.

Install

Axiom needs llc from LLVM, and a C compiler for the final link.

# macOS
xcode-select --install
brew install llvm
export PATH="$(brew --prefix llvm)/bin:$PATH"

# Debian and Ubuntu
sudo apt-get install -y llvm clang

Then install the compiler:

curl -fsSL https://raw.githubusercontent.com/chrispaig3/axiom/stable/scripts/install.sh | bash
export PATH="$HOME/.axiom/bin:$PATH"

The installer downloads a prebuilt archive for macOS or Linux on arm64 and checks its SHA-256. Before it replaces anything, it builds and runs a small program with the new compiler. It only ever replaces an installation it made itself. On any other host it stops and points you here.

On any other host, including linux-x86_64, build from source. The repository carries the compiler's own LLVM IR in bootstrap/, so all you need is the prerequisites above:

git clone https://github.com/chrispaig3/Axiom.git && cd Axiom
./scripts/bootstrap-from-seed.sh --install .axiom-bin
export PATH="$PWD/.axiom-bin:$PATH"

CONTRIBUTING explains what the bootstrap does.

Targets

--target picks the platform to generate code for. That sets the syscall ABI and the standard library's platform modules:

axiom --target=linux-aarch64 emit-llvm main.ax -o main.ll

Supported: darwin-aarch64, linux-aarch64. The default is your host.

A target is supported when a CI job executes what the compiler emits there. Both supported targets run the whole test battery on every change, and each ships a prebuilt archive.

Source-only: darwin-x86_64, freebsd-aarch64, freebsd-x86_64, linux-x86_64, windows-aarch64, windows-x86_64, baremetal-aarch64. The compiler emits code for each, and CI assembles that code on every change. CI runs the test battery on none of them, so they aren't supported, and no prebuilt archive is published for them. CI builds the compiler from the seed in bootstrap/ on linux-x86_64, and on freebsd-x86_64 and freebsd-aarch64 in FreeBSD 14.4 VMs. No runner builds it on darwin-x86_64. The compiler doesn't run on Windows, so windows-aarch64 and windows-x86_64 are targets you cross-compile to from Linux or macOS. No runner builds the compiler on baremetal-aarch64; its embedded image checks and optional QEMU execution are described in the embedded guide.

Quick start

Start a project and run it:

axiom new hello && cd hello && axiom run
Hello from Axiom! 🚀

axiom new writes Main.ax and an axiom.pkg manifest. Inside a project, run and build need no file name.

Here is a slightly bigger program. Put it in shapes.ax:

(import IO)

(data Shape
  (Circle { r : Float })
  (Rect { w : Float, h : Float })
  (Triangle { b : Float, h : Float }))

(:: area (-> Shape Float))
;@axiom:restrict(no-io)
(fn (area s)
  (match s
    ((Circle {r = r}) (* 3.14159 (* r r)))
    ((Rect {w = w, h = h}) (* w h))
    ((Triangle {b = b, h = h}) (/ (* b h) 2.0))))

(:: report (-> String Shape Int))
;@axiom:effect(io)
(fn (report name s)
  {
    (let a (area s))
    (println "{name:<10}{a:>8.2}")
  })

(:: main ())
;@axiom:effect(io)
(fn (main)
  {
    (report "circle" (Circle 2.0))
    (report "rect" (Rect 3.0 4.5))
    (report "triangle" (Triangle 4.0 3.0))
  })
axiom run shapes.ax
circle       12.57
rect         13.50
triangle      6.00

Shape is a sum type with named fields, and area handles every case. area promises it performs no I/O, and the compiler holds it to that. report prints, so it says so with effect(io). Delete that line and the compiler tells you the claim is missing.

When a match misses a case, the compiler names the case and offers the fix:

(data Light
  (Red)
  (Amber)
  (Green))

(:: next (-> Light Light))
(fn (next l)
  (match l
    ((Red) (Green))
    ((Green) (Amber))))
error[AX3005]: non-exhaustive pattern match: missing Amber
 --> light.ax:8:10
  |
8 |   (match l
  |          ^ this `match` does not cover: Amber
  |
  = help: add the missing arms, each a `todo` until it is written ~>
              ((Amber) (todo "Amber"))
  = help: import `todo` from IO ~>
          (import IO (todo))
  = help: run `axiom explain AX3005` for a full explanation

compilation failed due to 1 previous error

The commands you'll use most:

axiom run shapes.ax             # compile and run
axiom build shapes.ax -o shapes # keep the native executable
axiom check shapes.ax           # type-check and verify effects, no code generation
axiom test                      # run every function whose name starts with test
axiom fmt shapes.ax             # the one canonical layout
axiom explain AX3005            # the full explanation for any error code
axiom repl                      # Axiom 0.7.9 - REPL

IO is part of Axiom's own standard library, so the shapes binary calls no C library function, for printing or for allocation.

For programs the size of real work, examples/ has a batch job over a million records, and the generator that writes this repository's standard library reference.

Documentation

Start at Read Axiom's docs. The main references are:

Read Use
Language Syntax, types, effects and tools
Standard library Recipes, including TCP with Net
Public API Generated signatures and effects
Examples Complete programs
Feature status Supported behaviour and limits

Editor setup, Rust, databases, cryptography and embedded guides are linked from the docs index. Compiler contracts and assurance records have their own development reading path there.

Contributing

Issues and pull requests are welcome. CONTRIBUTING.md walks through the project layout, how the compiler works, and how to add a diagnostic or a standard library function. The rule every change follows is if you claim it, gate it: every claim is backed by a test that runs in CI.

If Axiom is useful to you, star the repository so other people can find it, and fork it to start your first contribution.

License

MIT. See LICENSE.

About

The Functional Systems Language

Resources

Contributing

Security policy

Stars

16 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages