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.

DecisionCost it removes
^fn f(x) = exprNo function, no return, no braces: about 6 tokens per function.
\x: x * 2An inline callback costs 2 tokens of overhead instead of a named declaration.
xs |> map(f) |> sumNo 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 ??= vEach replaces a 4 to 7 token conditional.
sum, uniq, group_byA guessable standard library means no reimplementing, and none of the bugs that come with it.
Diagnostics that name the fixSaves 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.

Documentation