AI Programming Guide
Everything an AI agent needs to write correct AXON programs. Critical rules, type system reference, common pitfalls, and complete syntax examples.
Critical Rules
⚠️ Every AI Agent Must Follow These Rules
- Every literal must be typed. Write
(i32 42), never bare42. There are no implicit type conversions. - Every function call requires the
callkeyword. Write(call foo (i32 1)), never(foo (i32 1)). mainmust returni32. The entry point is always(fn main () i32 ...)and must return ani32exit code.- All expressions in a block are evaluated but only the last expression's value is the block's result.
- Enums are nominal types. You cannot compare enums of different types or use bare integers where enums are expected.
- Match must be exhaustive. Cover all enum variants or use
_wildcard for integer/bool match.
Program Template
Every AXON program follows this structure. Copy this skeleton and fill in your logic.
(module ;; External function declarations (extern print_i64 ((n i64)) void) ;; Enum declarations (enum Color i32 ((Red 0) (Green 1) (Blue 2))) ;; Struct declarations (struct Point ((x i32) (y i32))) ;; Helper functions (fn helper ((x i32)) i32 (add x (i32 1))) ;; Entry point — must return i32 (fn main () i32 (block (call print_i64 (cast i64 (call helper (i32 41)))) (i32 0))))
Type Hierarchy
AXON has a small, explicit type system. Every value has exactly one type at all times.
| Category | Types | Sizes | Notes |
|---|---|---|---|
| Integers | i8, i16, i32, i64 | 1, 2, 4, 8 bytes | Signed, two's complement |
| Unsigned | u8, u16, u32, u64 | 1, 2, 4, 8 bytes | Unsigned integers |
| Floats | f32, f64 | 4, 8 bytes | IEEE 754 |
| Boolean | bool | 1 byte | true / false literals |
| Void | void | 0 bytes | Used for functions with no return value |
| Pointers | (ptr T) | 8 bytes | Typed pointer to T |
| Arrays | (array T N) | sizeof(T) × N | Fixed-size, value-type |
| Structs | (struct Name (fields...)) | Sum of fields | Named, value-type |
| Enums | (enum Name iN (variants...)) | Backing int size | Nominal, explicit values |
| Sum Types | (sum Name ((V1 types...) ...)) | i32 tag + max(payload) aligned | Tagged union with payloads |
| Function Ptrs | (fnptr (params...) ret) | 8 bytes | First-class callable |
Common Anti-Patterns
These are the most frequent mistakes AI agents make. Study these carefully.
❌ Missing Module Wrapper
;; WRONG — no module wrapper (fn main () i32 (i32 0)) ;; CORRECT (module (fn main () i32 (i32 0)))
❌ Untyped Literal
;; WRONG — bare literal (add x 1) ;; CORRECT — typed literal (add x (i32 1))
❌ Missing call Keyword
;; WRONG — no call keyword (print_i64 (i64 42)) ;; CORRECT (call print_i64 (i64 42))
❌ Mismatched If Types
;; WRONG — branches return different types (if cond (i32 1) (i64 2)) ;; CORRECT — both branches same type (if cond (i32 1) (i32 2))
Quick Reference
Literals
(i32 42) ;; integer (i64 -100) ;; negative (f64 3.14) ;; float (bool true) ;; boolean (u8 255) ;; unsigned "hello" ;; string
Control Flow
(if cond then else) (while cond body) (block expr1 expr2) (match val (pattern1 result1) (pattern2 result2) (_ default))
Variables
;; declare + initialize (let x i32 (i32 10)) ;; mutate (set x (i32 20)) ;; constants (const PI f64 (f64 3.14159))
Functions
;; declaration (fn add ((a i32) (b i32)) i32 (add a b)) ;; calling (call add (i32 1) (i32 2)) ;; extern (extern puts ((s (ptr u8))) i32)
Types
;; enum (enum Dir i32 ((N 0) (S 1) (E 2) (W 3))) ;; struct (struct Vec2 ((x f64) (y f64))) ;; function pointer (fnptr ((i32)) i32)
Enum Guide
Declaration
Enums are nominal types with an explicit integer backing type and explicit variant values.
(enum Direction i32 ((North 0) (South 1) (East 2) (West 3)))
Enum Literals
Reference enum variants with the type name followed by the variant name.
(let d Direction (Direction North)) (set d (Direction South))
Comparison
Enums support eq and ne comparisons between values of the same enum type.
(eq d (Direction North)) ;; returns bool (ne d (Direction South)) ;; returns bool
Casting
Enums can be cast to their backing integer type.
(cast i32 (Direction East)) ;; yields (i32 2)
Pattern Matching Guide
Enum Match (exhaustive)
All variants must be covered. No wildcard needed when all variants are listed.
(match color ((Color Red) (i32 1)) ((Color Green) (i32 2)) ((Color Blue) (i32 3)))
Integer Match with Wildcard
Integer match requires a _ wildcard fallback since integers have infinite range.
(match x ((i32 0) "zero") ((i32 1) "one") (_ "other"))
Bool Match
Both true and false must be covered for exhaustiveness.
(match flag ((bool true) (i32 1)) ((bool false) (i32 0)))
Match as Expression
Match is an expression — it returns a value. All arms must return the same type.
(let result i32 (match direction ((Direction North) (i32 0)) ((Direction South) (i32 1)) ((Direction East) (i32 2)) ((Direction West) (i32 3))))
Sum Types Guide
Declaration
Sum types (tagged unions) have an i32 tag and variant-specific payload data. Each variant can carry zero or more typed fields.
;; A sum type with two variants: ;; None — no payload ;; Some — carries an i64 (sum Option ((None) (Some i64))) ;; A sum type with three variants and mixed payloads (sum Shape ((Circle f64) (Rect f64 f64) (Empty)))
Construction (Dot Notation)
Construct sum type values using Type.Variant dot notation, followed by payload arguments if the variant has them.
;; Variant with payload (let x Option (Option.Some (i64 42))) ;; Variant without payload (let y Option (Option.None))
Pattern Matching with Bindings
Match on sum type variants and bind payload fields to names. Matching must be exhaustive — cover all variants.
(match opt ;; bind the i64 payload to 'val' ((Option.Some val) val) ;; no payload — return default ((Option.None) (i64 0)))
Anti-Patterns
❌ Missing Payload Binding
;; WRONG — Some has a payload, must bind it ((Option.Some) (i64 0)) ;; CORRECT — bind the payload ((Option.Some val) val)
❌ Wrong Construction Syntax
;; WRONG — bare variant name (Some (i64 42)) ;; CORRECT — Type.Variant dot notation (Option.Some (i64 42))
❌ Non-Exhaustive Match
;; WRONG — missing None variant (match opt ((Option.Some val) val)) ;; CORRECT — all variants covered (match opt ((Option.Some val) val) ((Option.None) (i64 0)))
Function Pointers Guide
fnptr Type
Function pointer types describe the signature of callable function values.
;; A function pointer that takes an i32 and returns i32 (fnptr ((i32)) i32) ;; A function pointer that takes two i64s and returns bool (fnptr ((i64) (i64)) bool)
Storing Function References
Named functions auto-coerce to fnptr when assigned to a variable of fnptr type.
(fn double ((x i32)) i32 (mul x (i32 2))) ;; auto-coerce named function to fnptr (let f (fnptr ((i32)) i32) double)
Indirect Calls
Use call_indirect to invoke a function through a pointer.
(call_indirect f (i32 21)) ;; returns (i32 42)
Auto-Coercion
Named functions can be passed directly where a fnptr parameter is expected.
(fn apply ((f (fnptr ((i32)) i32)) (x i32)) i32 (call_indirect f x)) ;; pass named function — auto-coerced to fnptr (call apply double (i32 5)) ;; returns (i32 10)
Operators
Arithmetic Operators
| Operator | Syntax | Description | Operand Types |
|---|---|---|---|
add | (add a b) | Addition | int, float |
sub | (sub a b) | Subtraction | int, float |
mul | (mul a b) | Multiplication | int, float |
div | (div a b) | Division | int, float |
mod | (mod a b) | Modulo | int only |
Comparison Operators
| Operator | Syntax | Description | Returns |
|---|---|---|---|
eq | (eq a b) | Equal | bool |
ne | (ne a b) | Not equal | bool |
gt | (gt a b) | Greater than | bool |
lt | (lt a b) | Less than | bool |
ge | (ge a b) | Greater or equal | bool |
le | (le a b) | Less or equal | bool |
Both operands must be the same type. Comparison operators also work on enum types (eq/ne only).