Skip to content

Axon for Python Developers

If you are coming from Python, you already understand Axon’s purpose: let AI models write efficient native code without fighting the language. Axon takes the runtime model Python programmers love (dynamic, REPL-friendly, batteries-included) and replaces the slow interpreter with a static, AI-native compiler.

Python is the de facto language of AI/ML. Its dynamic semantics and rich ecosystem make it the fastest path from idea to prototype. But every hot loop eventually hits the GIL, the interpreter overhead, or the ~50× performance gap versus native code. The conventional escape hatches — Cython, Numba, ctypes — all force you to leave Python and write foreign code that the LLM will get subtly wrong.

Axon closes that gap without leaving the source language. AI agents that already write Python can write Axon with one extra rule: parentheses go around everything. The output compiles to the same native code you’d get from Cython, with no Python runtime in production.

The same recursive Fibonacci:

Python (interpreted, no static types, no compilation step):

def fib(n: int) -> int:
if n < 2:
return n
return fib(n - 1) + fib(n - 2)
print(fib(35))

Axon (compiled to native code via QBE → clang → binary):

(fn fib ((n i64)) i64
(if (lt n (i64 2))
n
(add (call fib (sub n (i64 1)))
(call fib (sub n (i64 2))))))
(fn main () i32
(call print_i64 (call fib (i64 35)))
(i32 0))

The Axon version is more verbose — that is the price of explicit, AI-friendly syntax. In exchange you get a single binary that runs at native speed with no interpreter.

PythonAxon
def foo(x):(fn foo ((x i64)) ...)
return xlast expression value
if x: return y else: return z(if x y z)
for i in range(n):(for ((i i64)) (range (i64 0) n (i64 1)) ...)
import numpy as np(import np "std/math.axs")
print(x)(call print_i64 x)
def __init__(self):structs with (fn new (...) ...) constructors
try/except(try ... (catch e ...))
list comprehensions(map f xs) over the collections module
  • No duck typing. Every parameter and binding has a static type. The compiler rejects (add (i64 1) "hello") at build time.
  • No None semantics. Use (Option T) from std/option_types for “may not exist” — the compiler enforces that you check before unwrapping.
  • No GIL, no interpreter. Every Axon binary is a single statically-linked native executable.
  • S-expression syntax. Everything is a parenthesised list. The AST is 1:1 with the surface syntax.
  • No import magic. Modules are explicit files; you list each one you use.
  • Memory management is explicit. (alloc T) returns (ptr T), (free ptr) releases it. There is no GC.
  • Compiled, not interpreted. There is no python -i myprogram.py equivalent — you compile, then run the binary.
PythonAxon
with open(path) as f:(with_file path (fn (f) (call f.read)))
@dataclass class Foo:(struct Foo ((x i64) (y string)))
Optional[int](Option i64)
for k, v in d.items():(for-each d (fn (k v) ...))
lambda x: x + 1(fn ((x i64)) (add x (i64 1)))
try / except ValueError as e:(try ... (catch e ...))

Stay in Python for:

  • One-off scripts and notebooks
  • Glue code that orchestrates existing tools
  • Library exploration (you don’t know the API yet)

Reach for Axon for:

  • The hot inner loop of a model (loss, gradient, dataloader)
  • Anything that ships to production users as a binary
  • Code that must run on a serverless / edge runtime with a 50MB cold-start budget
  • Code where the LLM has to write the same logic 1000 times and you need it to be correct every time
  • Syntax: S-expressions instead of indentation. Same “batteries-included” feeling via std/*.axs.
  • Performance: 30-100× faster than CPython for numeric code, no GIL, no interpreter.
  • Concurrency: Green-thread cooperative scheduling via std/evloop + actor-style message passing.
  • Packaging: axpm for source deps, .axpkg for binary artifacts.
  • Migration cost: One-time syntax learning; the underlying mental model (types, scoping, modules) maps cleanly.