AxiomScript
A general-purpose language written for language models, not for people.
It optimises for one measurable thing: how many tokens it costs a model to write a correct program. Sigils instead of keywords, significant indentation, expression bodies and a standard library whose names you can guess.
- v0.9.3
- Node 18+
- C11 runtime
- WebAssembly
- MIT
hello.ax
^fn fib(n) = n < 2 ? n : fib(n-1) + fib(n-2)
^main:
print(fib(20)) // 6765
evens = [1,2,3,4] |> filter(\n: n % 2 == 0)
print(evens |> sum) // 6
$ node main.js hello.ax
Why it looks like this
Every syntactic decision removes a cost a model would otherwise pay.
| Decision | Cost it removes |
|---|---|
^fn f(x) = expr | No function, no return, no braces: about 6 tokens per function. |
\x: x * 2 | An inline callback costs 2 tokens of overhead instead of a named declaration. |
xs |> map(f) |> sum | No nesting to balance, so no mismatched-paren retries. |
?* value: | A six-way dispatch costs about 24 tokens instead of about 48 as an if/elif ladder. |
a ?? b, x ??= v | Each replaces a 4 to 7 token conditional. |
sum, uniq, group_by | A guessable standard library means no reimplementing, and none of the bugs that come with it. |
Diagnostics that name the fix | Saves a whole generate, run, fail, retry cycle: the most expensive thing a model can do. |
A quick tour
patterns.ax
?* node: // patterns take a value apart
Add(l, r): v = ev(l) + ev(r) // record pattern, binds l and r
Num(v) if v > 0: acc += v // guard sees the bindings
[x, y]: v = x + y // array pattern
_: ^throw "?"flow.ax
total = orders |> map(\o: o.price) |> sum
adults = people.filter(\p: p.age >= 18).sort_by("age")
q, r = divmod(17, 5) // destructuring
cfg = from_json(read("config.json", "{}"))The checker writes its messages for the model: every diagnostic carries a message_for_agent that says what to change. It catches wrong argument counts, undeclared fields, mistyped names, undefined functions and unreachable code before anything runs.
Running a program
$ node main.js prog.ax # run it $ node main.js prog.ax --check # parse and check only $ node main.js prog.ax --json # machine-readable result $ node main.js --repl # an interactive session $ node main.js world.ax --terminal # render a 3D world as text
$ cd native && make # one ~600 KB binary $ ./axiom ../examples/calc.ax -- "2 * (3 + 4)" $ make wasm # the same runtime as WebAssembly
Two runtimes, one language: the JavaScript reference and a C11 runtime that starts in about 1.6 ms. Differential tests keep them identical, down to the last bit of a simulation's numbers. --sandbox denies file writes and subprocesses unless you allow them.