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.
At a glance
Quick Start
Axon ships as a Node.js CLI. Install from source and run the compiler against any .axn file.
Hello, Axon
Design Goals
| Goal | What it means in practice |
|---|---|
| Unambiguous grammar | Every 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 level | Types 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 structure | No class hierarchies. No this. Data is records; behaviour is functions that take records. |
| Exhaustive by default | Pattern matches warn when not exhaustive. Tagged unions are fully covered or the checker complains. |
| AI-first output | Generated JS embeds JSDoc with all Axon metadata — intent, constraints, effects — so downstream tools can reason about it. |
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.
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.
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.
Lambda expressions
.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.
Types & Constraints
Axon's primitive types map directly to JavaScript. Type aliases add names; where clauses add runtime-enforced predicates.
Primitive types
| Axon type | JS equivalent | Notes |
|---|---|---|
| int | number (integer) | No distinct integer runtime; validated by constraint if needed |
| float | number | – |
| string | string | Supports interpolation and triple-quote literals |
| bool | boolean | – |
| void | undefined | Return type for side-effecting functions |
| list<T> | Array | – |
Type aliases
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.
__validate_TypeName check at function entry for every
constrained-type parameter. You never write the guard manually — the constraint is the source of truth.
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.
Immutable updates
Records are updated functionally. The spread operator returns a new record with changed fields; the original is untouched.
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.
Enum pattern matching
Use the Enum.Variant syntax inside a match expression.
Generated output
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.
tag property used by pattern matching.
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
when guards
Any arm can carry a boolean guard. Guards have full access to names bound by the pattern.
Tagged union patterns
Pattern types
| Pattern syntax | Matches |
|---|---|
| _ | Anything (wildcard, no binding) |
| n | Anything, binds subject to n |
| "hello" | Exact string literal |
| 42 | Exact number literal |
| true / false | Exact boolean |
| Circle | Tagged union variant (unit or payload), by tag name |
| Circle { r } | Tagged union variant, destructures payload field r |
| n when expr | Binding pattern with guard expression |
Pipelines
The pipeline operator |> threads a value through a sequence of transformations. Each step receives the previous step's result as its first argument.
|> 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.
Destructuring
Destructuring let unpacks object and array values into named bindings in a single statement.
Strings
String interpolation
Any string containing {ident} or {ident.prop} is automatically treated as an interpolated string. No extra syntax required.
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.
{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.
Optional Chaining & Nullish Coalescing
Safe navigation through potentially-null values without nested conditionals.
| Operator | Meaning |
|---|---|
| a?.b | Access 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 ?? b | Return a unless it is null/undefined, then return b |
Control Flow
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.
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
? — early-return on Err
| Helper | Signature | Description |
|---|---|---|
ok(v) | T → Result<T> | Wrap a success value |
err(msg) | string → Result<never> | Wrap an error message |
is_ok(r) | Result → bool | True when the result is Ok |
is_err(r) | Result → bool | True when the result is Err |
unwrap(r) | Result<T> → T | Extract value; throws if Err |
unwrap_or(r, fallback) | Result<T> → T → T | Extract value or return fallback |
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.
@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).
@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.
@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.
@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.
@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).
@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.
@memo requires @pure and @total. The compiler will
warn if you annotate a function with @memo without both.
@exhaustive
Placed on a match expression to opt into strict exhaustiveness checking. The checker verifies that all variants of a tagged union are covered.
@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.
@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.
@throws goes immediately before the fn keyword, on the same line.
It can be combined with other annotations: @pure @throws fn foo().
Standard Library
The Axon stdlib is a small set of higher-order functions prepended to every generated file. All functions are pure.
| Function | Signature | Description |
|---|---|---|
| map(xs, f) | list → fn → list | Transform each element |
| filter(xs, f) | list → fn → list | Keep elements where f returns true |
| reduce(xs, f, init) | list → fn → any → any | Fold left |
| find(xs, f) | list → fn → any | First matching element or undefined |
| some(xs, f) | list → fn → bool | True if any element matches |
| every(xs, f) | list → fn → bool | True if all elements match |
| sum(xs) | list<number> → number | Sum of all elements |
| max(xs) | list<number> → number | Maximum value |
| min(xs) | list<number> → number | Minimum value |
| flat(xs) | list → list | Flatten 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 → number | Constrain to [lo, hi] |
| el(tag, attrs, ...) | string → obj → DOM | Create DOM element |
| mount(el, sel) | DOM → string → void | Mount element at CSS selector |
| __axon_tests | list | Registered @test declarations |
| __runAxonTests() | () → void | Execute all tests, print summary |
| Result helpers — v0.6 | ||
| ok(v) | T → Result<T> | Wrap a success value in Ok |
| err(msg) | string → Result | Wrap an error message in Err |
| is_ok(r) | Result → bool | True if result is Ok |
| is_err(r) | Result → bool | True if result is Err |
| unwrap(r) | Result<T> → T | Extract value; throws if Err |
| unwrap_or(r, fallback) | Result<T>, T → T | Extract value or return fallback |
CLI
| Command | Description |
|---|---|
axon input.axn output.js | Transpile a single Axon source file to JavaScript |
axon --test input.axn | Run all @test declarations and print pass/fail summary. Exits with code 1 on failure. |
axon --bundle entry.axn out.js | v0.5 Bundle a multi-file project. Resolves all imports recursively, topo-sorts modules, emits one JS file. |
axon --check input.axn | v0.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. |
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.
| Form | Example | Description |
|---|---|---|
decimal | 1_000_000 | Underscore separators for readability; stripped at compile time |
0x… | 0xFF_00_00 | Hexadecimal literal; notation preserved in output |
0b… | 0b1010_1010 | Binary literal; notation preserved in output |
float | 3.141_592 | Underscores allowed before or after the decimal point |
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.
$ 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.
$ 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.
$ 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
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.
<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.
| Field | Type | Description |
|---|---|---|
js | string | null | Transpiled JavaScript, or null if there were parse errors |
errors | Error[] | Parse or compiler errors (see below). Empty array on success. |
warnings | Warning[] | Checker warnings (@pure, @exhaustive, @effects). May be non-empty even when js is set. |
Error object shape
| Field | Type | Description |
|---|---|---|
message | string | Human-readable error message including line and column |
line | number | 1-based source line number |
col | number | 1-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".
Modules
Split a project across multiple .axn files. Use import to bring names into scope and export to mark declarations as public.
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") == "█" }
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()
| Syntax | Description |
|---|---|
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.
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.
| Syntax | Notes |
|---|---|
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 binding | Each emits a separate JSDoc tag — all constraints are recorded. |
| Works with any type | Works on int, string, float, records, tagged unions, etc. |
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.
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
Generic functions
Generic type aliases
Pair<int, string> compiles to an ordinary JS object.
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.
| Syntax | Notes |
|---|---|
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() -> T | Method signature using a function type expression. See fn(T)->U Types. |
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.
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.
| Syntax | Meaning |
|---|---|
fn() -> T | Zero-argument function returning T |
fn(A) -> B | Single-argument function from A to B |
fn(A, B) -> C | Two-argument function |
fn(T) -> void | Side-effecting callback |
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.
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).
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.
| Syntax | Meaning |
|---|---|
store Name { f: T = v } | Declare a reactive store with field f defaulting to v |
Name.field | Read 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) |
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 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.
| Syntax | Meaning |
|---|---|
async fn name(…) { … } | Async function — returns Promise<T> |
await expr | Await 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 |
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.
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.
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.
Version History
enumtype —enum Color = Red | Green | Blue; compiles toObject.freeze({ Red: 'Red', … }); supportsEnum.Variantpattern matching inmatch- Numeric separators —
1_000_000,0xFF_FF,0b1010_1010; underscore stripped at compile time - Hex & binary literals —
0xFFand0b1010fully supported; notation preserved in generated JS - Multi-line lambdas —
item => { 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;errorsmay contain multiple items; version string is"0.9.5"
axon --check <file>— static analysis only; reports checker warnings and parse errors without emitting JSaxon --fmt <file>— canonical formatter; normalizes indentation, operator spacing, brace padding, and trailing whitespaceaxon --watch <file> [output.js]— file watcher; recompiles automatically on every saveaxon.compiler.js— browser-compatible IIFE bundle; full Axon compiler running client-side viaAxonCompiler.compile(src)- Structured error objects —
compile()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
async fn— asynchronous function declarations that transpile to async arrow functionsawait expr— resolve a Promise inside an async function; valid at statement or expression levelstore Name { field: Type = default }— reactive state with.set(patch), getters, and.subscribe(fn); compiles to a self-contained IIFEon StoreName.change { … }— reactive subscription sugar; desugars toStoreName.subscribe(() => { … })@effectsenforcement — checker warns if an async fn lacks an@effectsdeclarationdelay(ms)stdlib — Promise-based async sleep helper for use withawait- Bare
return—returnwithout a value now valid in all function bodies - Demo: Chronicle — reactive fantasy kingdom log; reactive
store,async fn tick(),await delay(), andon Kingdom.change { render() }
- Generic type parameters —
record Pair<A, B>,fn map<T, U>,type Maybe<T>; erased at runtime (JS-transparent) interfacedeclarations — structural type contracts; emitted as JSDoc@interfacecommentsfn(T) -> Utype expressions — first-class function types usable in record fields, interfaces, and signatureslet 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 immutableAppStaterecord
- Built-in
Resulttype —ok(value)/err(message)constructors;is_ok,is_err,unwrap,unwrap_orin stdlib ?propagation operator —let n = parse(s)?returnsErrimmediately; line-aware disambiguation from ternary@throwsannotation — marks fallible functions; checker warns ifok()/err()are never calledrefine x: "claim"— semantic value narrowing; structured comment today, model-checked in v1.0- Pre-function annotations —
@throws fn foo()syntax now valid - Demo: Dungeon Configurator —
config.axnwith chained@throwsparsers; precise per-field error messages
for i in lo..hi/lo..=hi— exclusive and inclusive range loopsfor x in array— forEach loop; compiles tofor...ofbreak/continue— full loop controllet mut x = val— explicit mutable binding
- Compiler: top-level
let& bare expressions —TopLevelLetandTopLevelExprAST 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
import { x, y } from "./path"— multi-file projects; relative path resolution per-moduleexport fn / export type / export record— declare public API surface; bundler tracks exported symbolsaxon --bundle <entry> [out.js]— recursive import resolution, topo-sort, stdlib emitted once- Auto-bundle in
--test— files with imports are auto-bundled before running@testdeclarations - Optional
ifparens — bothif (cond) { }andif cond { }are valid - Return-type short-form —
fn f(x) -> T = exprandfn f(x) -> T { block }both valid - Nested
fnin blocks — local helper functions inside blocks, emitted asletlambdas - Demo: Dungeon Map Toolkit — 4-file module demo introducing
import/exportacrosstiles,generator,renderer, andmain
whenguards inmatch— 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 types —
type T = | Variant { fields } | Unit; factory fns + frozen constants @testdeclarations — inline tests with--testCLI flag;__runAxonTests()for browser- Pipeline
|> as name— bind intermediate pipeline results to names; emits as IIFE block
- String interpolation —
"Hello {name}"compiles to a JS template literal automatically .fieldaccessor shorthand —.nameas implicit lambda in pipelines and higher-order calls- Param validation injection —
where-constrained type params auto-inject guard clauses at function entry @memoannotation — compile-timeMap-based memoization for@pure @totalfunctions
- Short-form functions —
fn name(args) = exprsingle-expression shorthand - Pipeline operator
|>— left-to-right functional composition - Expanded stdlib —
map,filter,reduce,find,sum,range,clamp - DOM helpers —
elandmountfor building UIs in pure Axon
- Core language —
fn,let,if/else,match, ternary - Type system — primitive types, type aliases,
whereconstraints, record types - Annotations —
@pure,@total,@intent,@effects,@exhaustive - Static checker —
@pureviolation detection, exhaustiveness analysis - Transpiler — Lexer → Parser → AST → Codegen pipeline; JSDoc metadata embedding
- VS Code extension — TextMate grammar for syntax highlighting
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.
- ✓
import { fn, type } from "./path" - ✓
export fn name ...declarations - ✓
axon --bundle— topo-sort multi-file bundle - ✓ Auto-bundle in
--testmode - ✓ Demo: Dungeon Map Toolkit (4 modules)
- ✓ Built-in
Result<T> = Ok { value } | Err { message } - ✓
?propagation operator — early-return onErr - ✓
@throwsannotation for explicit failure contracts - ✓
refine x: "prose claim"— semantic value narrowing - ✓ Demo: Dungeon Configurator with
config.axn
- ✓ Generic type params:
record Pair<A,B>,fn map<T,U> - ✓
interfacedeclarations — structural, not nominal - ✓
fn(T) -> Ufirst-class function type expressions - ✓
let infer x = expr— model-resolved type annotation - ✓ Demo: The Bazaar — typed RPG item shop
@effects is now a real contract. Reactive state and async I/O — pure functions stay pure.- ✓
async fndeclarations — transpile to async arrow functions - ✓
await exprinside async functions - ✓
@effectsenforced — 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
- Language Server Protocol (LSP) implementation
- Source maps — debug Axon in browser DevTools
axon fmt— canonical formatteraxon 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
- Frozen language specification
- Semver stability — no breaking changes without major bump
- Comprehensive stdlib with full type signatures
axon spec— extract@intent,refine, andexplainblocks as structured JSON for LLM consumption- Documentation site
- Package registry
likelymatch arms — pattern matching by semantic similarity rather than literal equality; arms become soft classifiers- Host-runtime embedding API — pluggable model for
likelyevaluation - Bundled lightweight embedding for offline use
- Demo: intent-driven input router