Axon Language Reference
v0.9.5 AI-native
Introduction

Axon Language Reference

Axon is an AI-native programming language that transpiles to JavaScript. It is designed from the ground up to be written, read, and reasoned about by language models — with unambiguous grammar, intent-first declarations, constraint-enforced types, and explicit effect tracking.

AI-native design
Every Axon feature exists because it makes AI-generated code safer or more legible — not because it mirrors conventions from human-ergonomic languages. OOP, mutable state, and implicit dispatch are absent by design.
Transpiles to JS Functional core Immutable by default Constraint types Intent annotations Exhaustive matching Built-in testing Pipeline composition

At a glance

axon

        
Getting Started

Quick Start

Axon ships as a Node.js CLI. Install from source and run the compiler against any .axn file.

shell

        

Hello, Axon

hello.axn

        
Philosophy

Design Goals

GoalWhat it means in practice
Unambiguous grammarEvery construct has exactly one parse. No statement/expression duality. No semicolon insertion edge cases.
Intent over ceremony@intent is a first-class declaration, not a comment. It becomes queryable metadata in generated JS.
Constraints at the type levelTypes carry where predicates. Guard clauses are injected automatically — they are never forgotten.
Explicit effects@pure, @total, @effects are compiler-checked contracts, not documentation.
Flat, scannable structureNo class hierarchies. No this. Data is records; behaviour is functions that take records.
Exhaustive by defaultPattern matches warn when not exhaustive. Tagged unions are fully covered or the checker complains.
AI-first outputGenerated JS embeds JSDoc with all Axon metadata — intent, constraints, effects — so downstream tools can reason about it.
Language Reference

Functions

All functions in Axon are declared with fn. The :: separator introduces the full type signature. Functions are first-class values and can be passed as arguments or returned from other functions.

Full-form function

The canonical form uses :: to separate the name from the typed signature, with the body in a block.

axon

        

Short-form function v0.5 expanded

When the body is a single expression, use = expr to eliminate the block. An optional return-type annotation is supported with ->. A block body { ... } is also valid without the :: sigil.

axon

        

Nested functions v0.5

A fn declaration inside a block body is emitted as a let-bound lambda — a local helper scoped to the enclosing function.

axon

        

Lambda expressions

axon

        

.field accessor shorthand

A bare .fieldName in any expression position is syntactic sugar for a single-argument lambda that accesses that field. Chained access is supported.

axon

        
Language Reference

Types & Constraints

Axon's primitive types map directly to JavaScript. Type aliases add names; where clauses add runtime-enforced predicates.

Primitive types

Axon typeJS equivalentNotes
intnumber (integer)No distinct integer runtime; validated by constraint if needed
floatnumber
stringstringSupports interpolation and triple-quote literals
boolboolean
voidundefinedReturn type for side-effecting functions
list<T>Array

Type aliases

axon

        

Constrained types with where

Any type alias can carry a where predicate. Functions parameterised by a constrained type automatically receive injected guard clauses — no manual validation needed.

axon

        
Auto-injected guards
The transpiler emits a __validate_TypeName check at function entry for every constrained-type parameter. You never write the guard manually — the constraint is the source of truth.
Language Reference

Records

Records are named structured data types — plain objects with known fields. They have no methods and carry no behaviour; that belongs in standalone functions.

axon

        

Immutable updates

Records are updated functionally. The spread operator returns a new record with changed fields; the original is untouched.

axon

        
Language Reference · v0.9.5

Enums

An enum declares a closed set of named string values. It compiles to a frozen, immutable object — safe to use as a constant, in pattern matching, and across module boundaries.

axon

        

Enum pattern matching

Use the Enum.Variant syntax inside a match expression.

axon

        

Generated output

js (generated)

        
Language Reference

Tagged Unions

Tagged unions (also called sum types or algebraic data types) express a value that is exactly one of several named variants. They are the preferred replacement for inheritance hierarchies.

axon

        
emitted JS

        
Unit vs. payload variants
Variants with no fields (unit variants) emit frozen constant objects. Variants with fields (payload variants) emit factory functions. Both carry a tag property used by pattern matching.
Language Reference

Pattern Matching

match is an expression, not a statement. Every arm produces a value. The checker warns when a match is not exhaustive unless a wildcard arm is present.

Basic patterns

axon

        

when guards

Any arm can carry a boolean guard. Guards have full access to names bound by the pattern.

axon

        

Tagged union patterns

axon

        

Pattern types

Pattern syntaxMatches
_Anything (wildcard, no binding)
nAnything, binds subject to n
"hello"Exact string literal
42Exact number literal
true / falseExact boolean
CircleTagged union variant (unit or payload), by tag name
Circle { r }Tagged union variant, destructures payload field r
n when exprBinding pattern with guard expression
Language Reference

Pipelines

The pipeline operator |> threads a value through a sequence of transformations. Each step receives the previous step's result as its first argument.

axon

        

|> as name — named intermediate results

Any pipeline step can be named with as. When present, the entire pipeline emits as an IIFE block with const bindings, making intermediates available for reuse or debugging.

axon

        
Language Reference

Destructuring

Destructuring let unpacks object and array values into named bindings in a single statement.

axon

        
Language Reference

Strings

String interpolation

Any string containing {ident} or {ident.prop} is automatically treated as an interpolated string. No extra syntax required.

axon

        

Triple-quote strings """..."""

Multiline string literals that preserve newlines exactly. A leading newline immediately after """ is stripped for idiomatic alignment. Support the same {ident} interpolation as regular strings. Compile to JavaScript template literals.

axon

        
Curly braces in strings
Axon treats {name} inside any string as interpolation. To emit a literal curly brace, avoid bare identifiers inside braces or use a variable name that won't collide. This is intentional — it removes the need for a separate template syntax.
Language Reference

Optional Chaining & Nullish Coalescing

Safe navigation through potentially-null values without nested conditionals.

axon

        
OperatorMeaning
a?.bAccess b on a; returns undefined if a is null/undefined
a?.[i]Index a at i; safe if a is null/undefined
f?.()Call f if it is not null/undefined
a ?? bReturn a unless it is null/undefined, then return b
Language Reference

Control Flow

axon

        
For loops (v0.5.2+)
Axon supports for i in lo..hi (exclusive range), for i in lo..=hi (inclusive range), and for x in array (forEach). Use break / continue for loop control. The standard library also provides map, filter, and fold for functional iteration. while loops are not supported — use recursion or for.
Error Handling · v0.6

Result Type & ? Propagation

Axon has a built-in Result<T> tagged union for explicit error handling. Construct values with ok() / err(), consume them with match or stdlib helpers, and chain fallible calls cleanly with the ? propagation operator.

Constructing and consuming Result

axon

        

? — early-return on Err

axon

        
HelperSignatureDescription
ok(v)T → Result<T>Wrap a success value
err(msg)string → Result<never>Wrap an error message
is_ok(r)Result → boolTrue when the result is Ok
is_err(r)Result → boolTrue when the result is Err
unwrap(r)Result<T> → TExtract value; throws if Err
unwrap_or(r, fallback)Result<T> → T → TExtract value or return fallback
? operator semantics
expr? evaluates expr. If the result is Err, it immediately returns that Err from the enclosing function. If it is Ok, it unwraps the value and execution continues. The enclosing function must also return Result — annotate it with @throws.
Annotations

@pure & @total

@pure declares that a function has no side effects — it does not access globals, mutate state, or call effectful methods. The checker verifies this statically.

@total declares that a function is defined for all inputs and will always return a value (no throws, no unbounded recursion).

axon

        
Checker enforcement
A @pure function that references console, Math.random, or any other global with side effects will produce a compiler warning. These are warnings, not hard errors, in v0.4 — errors are planned for v0.9.
Annotations

@intent

The single most important annotation in Axon. @intent is a machine-readable natural language description of what a function is for — not what it does mechanically, but why it exists. It is preserved as a JSDoc @intent tag in generated output.

axon

        
Why this matters for AI
A language model reading generated Axon output can query @intent tags to understand a function's purpose without executing it or reading its full body. This is the foundation for the v1.0 spec-extraction tool.
Annotations

@effects

Declares the set of side effects a function produces. In v0.4 this is a documentation annotation; it becomes a compiler-enforced contract in v0.8 (The Async & Reactive Update).

axon

        
Annotations

@memo

Wraps a @pure @total function in a Map-based memoization cache at compile time. Results are cached after the first call; subsequent calls with the same arguments return instantly.

axon

        
Requirements
@memo requires @pure and @total. The compiler will warn if you annotate a function with @memo without both.
Annotations

@exhaustive

Placed on a match expression to opt into strict exhaustiveness checking. The checker verifies that all variants of a tagged union are covered.

axon

        
Annotations

@test

Top-level inline test declarations. Tests are registered in __axon_tests at runtime and can be run via __runAxonTests() in the browser, or the CLI --test flag.

axon

        
CLI output

        
Annotations · v0.6

@throws

Mark a function as fallible. @throws fn f() -> Result<T> signals to the checker and to callers that this function may return Err. The static checker warns if a @throws result is silently ignored without a match or ? operator.

axon

        
Placement
@throws goes immediately before the fn keyword, on the same line. It can be combined with other annotations: @pure @throws fn foo().
Runtime

Standard Library

The Axon stdlib is a small set of higher-order functions prepended to every generated file. All functions are pure.

FunctionSignatureDescription
map(xs, f)list → fn → listTransform each element
filter(xs, f)list → fn → listKeep elements where f returns true
reduce(xs, f, init)list → fn → any → anyFold left
find(xs, f)list → fn → anyFirst matching element or undefined
some(xs, f)list → fn → boolTrue if any element matches
every(xs, f)list → fn → boolTrue if all elements match
sum(xs)list<number> → numberSum of all elements
max(xs)list<number> → numberMaximum value
min(xs)list<number> → numberMinimum value
flat(xs)list → listFlatten one level
keys(obj)object → list<string>Object.keys
values(obj)object → list<any>Object.values
entries(obj)object → list<[k,v]>Object.entries
range(n)int → list<int>[0, 1, …, n-1]
clamp(v, lo, hi)number×3 → numberConstrain to [lo, hi]
el(tag, attrs, ...)string → obj → DOMCreate DOM element
mount(el, sel)DOM → string → voidMount element at CSS selector
__axon_testslistRegistered @test declarations
__runAxonTests()() → voidExecute all tests, print summary
Result helpers — v0.6
ok(v)T → Result<T>Wrap a success value in Ok
err(msg)string → ResultWrap an error message in Err
is_ok(r)Result → boolTrue if result is Ok
is_err(r)Result → boolTrue if result is Err
unwrap(r)Result<T> → TExtract value; throws if Err
unwrap_or(r, fallback)Result<T>, T → TExtract value or return fallback
Runtime

CLI

shell

        
CommandDescription
axon input.axn output.jsTranspile a single Axon source file to JavaScript
axon --test input.axnRun all @test declarations and print pass/fail summary. Exits with code 1 on failure.
axon --bundle entry.axn out.jsv0.5 Bundle a multi-file project. Resolves all imports recursively, topo-sorts modules, emits one JS file.
axon --check input.axnv0.9 Static analysis only — no JS emitted. Reports checker warnings and parse errors.
axon --fmt input.axn [--write]v0.9 Format source. Without --write, formatted source goes to stdout. With --write, rewrites file in-place.
axon --watch input.axn [out.js]v0.9 Watch file and recompile on every save. Ctrl+C to stop.
Language Reference · v0.9.5

Numeric Literals

Axon v0.9.5 extends numeric literals with underscore separators, hexadecimal 0x…, and binary 0b… prefixes. Separators are stripped at compile time; the notation is preserved in generated JS output.

axon

        
FormExampleDescription
decimal1_000_000Underscore separators for readability; stripped at compile time
0x…0xFF_00_00Hexadecimal literal; notation preserved in output
0b…0b1010_1010Binary literal; notation preserved in output
float3.141_592Underscores allowed before or after the decimal point
Runtime · v0.9

New CLI Commands

Three new commands ship with v0.9.0, covering static analysis, formatting, and live recompilation.

axon --check

Runs the static checker without emitting any output file. Useful in CI or as a pre-commit hook.

shell
$ axon --check src/main.axn
✓  main.axn — no issues

$ axon --check src/main.axn
  WARNING [line 14]: @pure function 'render' accesses effectful global 'console'

axon --fmt

Canonical formatter. Normalises 2-space indentation, spacing around operators (=, ->, =>, ::, |>, binary arithmetic), brace padding, and trailing whitespace. Does not modify </> spacing to preserve generic type parameters.

shell
$ axon --fmt src/main.axn           # formatted source → stdout
$ axon --fmt src/main.axn --write   # rewrite in-place
✓  main.axn — formatted
✓  main.axn — already canonical     # if no changes needed

axon --watch

Watches a source file with fs.watch and recompiles on every save. Timestamped output for each recompile. Ctrl+C to stop.

shell
$ axon --watch src/main.axn dist/main.js
[14:02:11]  ✓  main.axn → main.js
Watching main.axn for changes… (Ctrl+C to stop)
[14:02:45]  ✓  main.axn → main.js
[14:03:12]  ✗  [line 8:3] Expected } but got EOF
Runtime · v0.9

Browser Compiler API

axon.compiler.js is a self-contained IIFE bundle that runs the full Axon compiler client-side. Load it in any web page — no server, no build step, no dependencies.

HTML
<script src="axon.compiler.js"></script>
<script>
  const { js, errors, warnings } = AxonCompiler.compile(source);
</script>

AxonCompiler.compile(source)

Transpiles an Axon source string to JavaScript. Always returns an object — never throws.

FieldTypeDescription
jsstring | nullTranspiled JavaScript, or null if there were parse errors
errorsError[]Parse or compiler errors (see below). Empty array on success.
warningsWarning[]Checker warnings (@pure, @exhaustive, @effects). May be non-empty even when js is set.

Error object shape

FieldTypeDescription
messagestringHuman-readable error message including line and column
linenumber1-based source line number
colnumber1-based column number
kind"parse" | "error"Error category

AxonCompiler.check(source)

Runs only the static checker. Returns { warnings }. Useful for lightweight lint-on-type without full codegen.

AxonCompiler.version

String — the compiler version, e.g. "0.9.0".

example

        
Language · v0.5+

Modules

Split a project across multiple .axn files. Use import to bring names into scope and export to mark declarations as public.

tiles.axn
export type Tile = | Floor | Wall | Door | Stairs | Chest

export fn tile_glyph(tag: string) -> string =
  match tag {
    | "Floor"  => "·"
    | "Wall"   => "█"
    | "Door"   => "▯"
    | _        => "?"
  }

@test "wall glyph" { tile_glyph("Wall") == "█" }
main.axn
import { tile_glyph } from "./tiles"
import { generate }   from "./generator"
import { render_map } from "./renderer"

fn main() {
  let map  = generate(20, 40, 1, 7777)
  let html = render_map(map)
  document.getElementById("output").innerHTML = html
}

main()
SyntaxDescription
import { a, b } from "./path"Bring named symbols into scope. Path is relative to the importing file. .axn extension is optional.
export fn name ...Mark a function as part of the module's public API.
export type T = ...Export a type alias or tagged union.
export record R { ... }Export a record type declaration.

The bundler resolves imports depth-first, topo-sorts modules so dependencies come before dependents, and emits a single JS file with the stdlib included once at the top. All bundled code shares a single flat scope — no runtime module system overhead.

AI-native · v0.6

refine

refine x: "prose claim" is an AI-native semantic narrowing statement. It annotates a binding with a human-readable constraint that is too nuanced for a type signature — emitted as structured JSDoc and queryable by AI tooling. It compiles to a no-op comment at runtime; the value is unchanged.

axon

        
SyntaxNotes
refine x: "claim"Annotates the binding x with a semantic constraint. x must be in scope. Claim is a free-form English string.
Multiple refine on one bindingEach emits a separate JSDoc tag — all constraints are recorded.
Works with any typeWorks on int, string, float, records, tagged unions, etc.
AI-native design
refine fills the gap between machine-checkable types and human intent. A type system can guarantee price: int — but it cannot guarantee "price must be a positive USD amount before tax." refine captures that intent in a form that language models can read, validate, and reason about.
Type System · v0.7

Generic Type Parameters

Add type parameters to record, fn, and type declarations using angle-bracket syntax. Type parameters are erased at compile time — no runtime overhead.

Generic records

axon

        

Generic functions

axon

        

Generic type aliases

axon

        
Erasure
Generic type parameters exist only in the Axon source. The compiler emits plain JavaScript — no wrappers, no runtime type objects. Pair<int, string> compiles to an ordinary JS object.
Type System · v0.7

Interfaces

Declare structural type contracts with interface. Any record that carries the required fields and methods satisfies the interface — no explicit implements keyword needed. Interfaces are emitted as JSDoc @interface comments.

axon

        
SyntaxNotes
interface Name { field: Type }Declares a structural contract. Any record with matching fields satisfies it.
interface Name<T> { ... }Generic interface — type param available in field and method types.
method: fn() -> TMethod signature using a function type expression. See fn(T)->U Types.
Structural, not nominal
Axon interfaces use structural typing. There is no implements declaration — a record satisfies an interface if its shape matches. This is intentional: it keeps AI-generated code composable without requiring explicit trait registration.
Type System · v0.7

fn(T) -> U Function Types

Function types are first-class in Axon. Use fn(A, B) -> C syntax anywhere a type is expected — in record fields, interface definitions, and generic function signatures.

axon

        
SyntaxMeaning
fn() -> TZero-argument function returning T
fn(A) -> BSingle-argument function from A to B
fn(A, B) -> CTwo-argument function
fn(T) -> voidSide-effecting callback
AI-native · v0.7

let infer

let infer x = expr is an AI-native annotation that signals the type of a binding should be resolved from context by the model — not written explicitly by the programmer. It compiles to an ordinary let with no runtime difference.

axon

        
AI-native intent
let infer is a signal to language model tooling: "I know this value has a type — resolve it from the surrounding context rather than asking me to spell it out." In long pipelines or generic chains, the type is often obvious from usage. infer makes that intent explicit and queryable via axon spec (v1.0).
Async & Reactive · v0.8

store

store Name { field: Type = default } declares a reactive mutable state container — an explicit effects boundary that separates pure logic from observable state. Getters expose each field; .set(patch) updates state and notifies all subscribers atomically.

axon

        
SyntaxMeaning
store Name { f: T = v }Declare a reactive store with field f defaulting to v
Name.fieldRead current field value (getter)
Name.set({ field: val })Patch state and notify all subscribers
Name.subscribe(fn)Register a callback, fired with new state on every change (and once immediately)
Compiled output
A store compiles to a self-contained IIFE that encapsulates a private _state object, a subscriber list, ES5-style get accessors for each field, and a set(patch) method that applies a shallow merge and calls all subscribers. Zero runtime dependency — pure JS.
Async & Reactive · v0.8

async fn & await

Prefix any function declaration with async to make it asynchronous. Inside an async fn, use await expr to resolve a Promise without blocking. The stdlib provides delay(ms) for timer-based pauses.

axon

        
SyntaxMeaning
async fn name(…) { … }Async function — returns Promise<T>
await exprAwait a Promise inside an async function
await delay(ms)Non-blocking pause for ms milliseconds (stdlib)
@effects ["timer"]Declare async effects — enforced by the checker
@effects enforcement
The static checker warns when an async fn is declared without @effects. Use @effects ["timer"] for delay()-based loops, @effects ["network"] for fetch/XMLHttpRequest, or @effects ["io"] for generic I/O. This keeps side-effect surfaces visible at the declaration site — readable by both humans and AI tools.
Async & Reactive · v0.8

on StoreName.change { … }

on StoreName.change { body } is syntactic sugar for registering a reactive subscription. The body runs once immediately when the subscription is registered, then again after every StoreName.set(…) call. Multiple subscriptions can target the same store.

axon

        
Desugar
on Kingdom.change { render() } compiles to Kingdom.subscribe(() => { render() }) — a plain JS function call. There is no virtual DOM, diffing, or framework magic. The subscriber list is maintained inside the store's IIFE closure.
Meta

Version History

v0.9.5 The Ergonomics Update Current
  • enum typeenum Color = Red | Green | Blue; compiles to Object.freeze({ Red: 'Red', … }); supports Enum.Variant pattern matching in match
  • Numeric separators1_000_000, 0xFF_FF, 0b1010_1010; underscore stripped at compile time
  • Hex & binary literals0xFF and 0b1010 fully supported; notation preserved in generated JS
  • Multi-line lambdasitem => { let x = f(item)\n x * 2 }; block body with implicit last-expression return
  • Multi-error reporting — parser collects all errors with panic-mode recovery; parse() returns { ast, errors }
  • AxonCompiler.compile() updated — browser bundle uses multi-error parser; errors may contain multiple items; version string is "0.9.5"
v0.9.0 The Developer Experience Update Stable
  • axon --check <file> — static analysis only; reports checker warnings and parse errors without emitting JS
  • axon --fmt <file> — canonical formatter; normalizes indentation, operator spacing, brace padding, and trailing whitespace
  • axon --watch <file> [output.js] — file watcher; recompiles automatically on every save
  • axon.compiler.js — browser-compatible IIFE bundle; full Axon compiler running client-side via AxonCompiler.compile(src)
  • Structured error objectscompile() returns { js, errors, warnings } with { message, line, col, kind } per error
  • Demo: Axon Playground — live in-browser IDE with split-pane editor, real-time transpilation, live result execution, and 10 preloaded examples
v0.8.0 The Async & Reactive Update Stable
  • async fn — asynchronous function declarations that transpile to async arrow functions
  • await expr — resolve a Promise inside an async function; valid at statement or expression level
  • store Name { field: Type = default } — reactive state with .set(patch), getters, and .subscribe(fn); compiles to a self-contained IIFE
  • on StoreName.change { … } — reactive subscription sugar; desugars to StoreName.subscribe(() => { … })
  • @effects enforcement — checker warns if an async fn lacks an @effects declaration
  • delay(ms) stdlib — Promise-based async sleep helper for use with await
  • Bare returnreturn without a value now valid in all function bodies
  • Demo: Chronicle — reactive fantasy kingdom log; reactive store, async fn tick(), await delay(), and on Kingdom.change { render() }
v0.7.0 The Type System Update Stable
  • Generic type parametersrecord Pair<A, B>, fn map<T, U>, type Maybe<T>; erased at runtime (JS-transparent)
  • interface declarations — structural type contracts; emitted as JSDoc @interface comments
  • fn(T) -> U type expressions — first-class function types usable in record fields, interfaces, and signatures
  • let infer x = expr — signals to AI tooling that the type should be resolved from context, not explicitly annotated
  • Demo: The Bazaar — RPG item shop with 20 typed items, generic filter/sort/map, interface Tradeable, and an immutable AppState record
v0.6.0 The Safety Update Stable
  • Built-in Result typeok(value) / err(message) constructors; is_ok, is_err, unwrap, unwrap_or in stdlib
  • ? propagation operatorlet n = parse(s)? returns Err immediately; line-aware disambiguation from ternary
  • @throws annotation — marks fallible functions; checker warns if ok()/err() are never called
  • refine x: "claim" — semantic value narrowing; structured comment today, model-checked in v1.0
  • Pre-function annotations@throws fn foo() syntax now valid
  • Demo: Dungeon Configuratorconfig.axn with chained @throws parsers; precise per-field error messages
v0.5.2 The Ergonomics Update Stable
  • for i in lo..hi / lo..=hi — exclusive and inclusive range loops
  • for x in array — forEach loop; compiles to for...of
  • break / continue — full loop control
  • let mut x = val — explicit mutable binding
v0.5.1 The Module Update — Patch Stable
  • Compiler: top-level let & bare expressionsTopLevelLet and TopLevelExpr AST nodes
  • Bundler correctness — output path argument fix; stdlib emitted exactly once per bundle
  • Dungeon demo overhaul — room-based generator, avalanche hash, door bottlenecks, torch sconces, immutable AppState
v0.5.0 The Module Update Stable
  • import { x, y } from "./path" — multi-file projects; relative path resolution per-module
  • export fn / export type / export record — declare public API surface; bundler tracks exported symbols
  • axon --bundle <entry> [out.js] — recursive import resolution, topo-sort, stdlib emitted once
  • Auto-bundle in --test — files with imports are auto-bundled before running @test declarations
  • Optional if parens — both if (cond) { } and if cond { } are valid
  • Return-type short-formfn f(x) -> T = expr and fn f(x) -> T { block } both valid
  • Nested fn in blocks — local helper functions inside blocks, emitted as let lambdas
  • Demo: Dungeon Map Toolkit — 4-file module demo introducing import / export across tiles, generator, renderer, and main
v0.4.0 The Guards & Unions Update Stable
  • when guards in match — boolean guard on any arm; binding patterns scope correctly via IIFE
  • ?. optional chaining — safe member, index, and call access on nullable values
  • ?? nullish coalescing — short-circuit fallback; precedence above ternary, below logical OR
  • Destructuring let — object ({ a, b }), rename ({ x: ax }), and array ([a, b]) forms
  • Triple-quote strings """...""" — multiline literals with interpolation, compile to template literals
  • Tagged union typestype T = | Variant { fields } | Unit; factory fns + frozen constants
  • @test declarations — inline tests with --test CLI flag; __runAxonTests() for browser
  • Pipeline |> as name — bind intermediate pipeline results to names; emits as IIFE block
v0.3.0 The Ergonomics Update Stable
  • String interpolation"Hello {name}" compiles to a JS template literal automatically
  • .field accessor shorthand.name as implicit lambda in pipelines and higher-order calls
  • Param validation injectionwhere-constrained type params auto-inject guard clauses at function entry
  • @memo annotation — compile-time Map-based memoization for @pure @total functions
v0.2.0 The Composition Update Stable
  • Short-form functionsfn name(args) = expr single-expression shorthand
  • Pipeline operator |> — left-to-right functional composition
  • Expanded stdlibmap, filter, reduce, find, sum, range, clamp
  • DOM helpersel and mount for building UIs in pure Axon
v0.1.0 Initial Release Stable
  • Core languagefn, let, if/else, match, ternary
  • Type system — primitive types, type aliases, where constraints, record types
  • Annotations@pure, @total, @intent, @effects, @exhaustive
  • Static checker@pure violation detection, exhaustiveness analysis
  • Transpiler — Lexer → Parser → AST → Codegen pipeline; JSDoc metadata embedding
  • VS Code extension — TextMate grammar for syntax highlighting
Meta

Roadmap to v1.0

Each milestone ships a demo that couldn't be written before it. Internal plumbing without a visible payoff doesn't ship.

v0.5 ✓
The Module Update
Shipped. Multi-file projects with recursive import resolution and a bundler.
  • import { fn, type } from "./path"
  • export fn name ... declarations
  • axon --bundle — topo-sort multi-file bundle
  • ✓ Auto-bundle in --test mode
  • ✓ Demo: Dungeon Map Toolkit (4 modules)
v0.6 ✓
The Safety Update
Shipped. First-class error handling without exceptions, built on tagged unions.
  • ✓ Built-in Result<T> = Ok { value } | Err { message }
  • ? propagation operator — early-return on Err
  • @throws annotation for explicit failure contracts
  • refine x: "prose claim" — semantic value narrowing
  • ✓ Demo: Dungeon Configurator with config.axn
v0.7 ✓
The Type System Update
Shipped. Parameterised types, structural interfaces, and model-resolved type annotations.
  • ✓ Generic type params: record Pair<A,B>, fn map<T,U>
  • interface declarations — structural, not nominal
  • fn(T) -> U first-class function type expressions
  • let infer x = expr — model-resolved type annotation
  • ✓ Demo: The Bazaar — typed RPG item shop
v0.8 ✓ current
The Async & Reactive Update
Shipped. @effects is now a real contract. Reactive state and async I/O — pure functions stay pure.
  • async fn declarations — transpile to async arrow functions
  • await expr inside async functions
  • @effects enforced — checker warns when async fn lacks declaration
  • store Name { field: Type = default } — reactive state with .set() and .subscribe()
  • on StoreName.change { ... } — reactive subscription sugar
  • delay(ms) stdlib helper — await delay(500)
  • ✓ Bare return — valid in all function bodies
  • ✓ Demo: Chronicle — reactive fantasy kingdom log
v0.9
The Tooling Update
The experience of working in Axon becomes as good as the language itself.
  • Language Server Protocol (LSP) implementation
  • Source maps — debug Axon in browser DevTools
  • axon fmt — canonical formatter
  • axon check — standalone lint step
  • VS Code: go-to-definition, hover types
  • Rich error messages with source context
  • explain { prose } blocks — structured semantic context in the AST; surfaced as IDE hover tooltips and model-queryable documentation
v1.0
Stability
Frozen spec, semver promise, and the AI-native payoff: queryable intent metadata.
  • Frozen language specification
  • Semver stability — no breaking changes without major bump
  • Comprehensive stdlib with full type signatures
  • axon spec — extract @intent, refine, and explain blocks as structured JSON for LLM consumption
  • Documentation site
  • Package registry
v1.1
The AI-Native Update
The constructs that only make sense when an AI is both author and reader. Requires a stable v1.0 spec to define their semantics.
  • likely match arms — pattern matching by semantic similarity rather than literal equality; arms become soft classifiers
  • Host-runtime embedding API — pluggable model for likely evaluation
  • Bundled lightweight embedding for offline use
  • Demo: intent-driven input router