Tutorial

Learn Axioma by running it

A short, hands-on tour — from a variable binding to a recursive logic rule. Every example below runs right here in the page.

▶ Edit any example and press Run — or /Ctrl+Enter. Same WebAssembly interpreter as the playground; nothing leaves your browser. interpreter: loading…
LESSON 1

Trace a value — the period

The most distinctive move in everyday Axioma: end a line with a period and it traces the value — prints it, no function call at all. Both halves are inspired by older languages: printing a value with a dot by Forth (where ., "dot", pops and prints the top of the stack), and ending a statement with a dot by Prolog (where every clause closes with .). Axioma's . does both at once — it shows a value and terminates the statement. (A trace shows the value as the language sees it, so a string keeps its quotes; println is the more familiar way to write clean output for a person.)

trace.axOpen in Playground ↗

Because the dot terminates a statement, several can share one line — and the playground traces the last line for you automatically, which is the you'll see in every example. (A dot directly before a digit is still a decimal point, so 3.14 is a number, not a trace.)

oneline.axOpen in Playground ↗
LESSON 2

Bindings — REBOL's set-word colon

Axioma binds a name to a value with a colon: name: value — no let, no var. The colon-binding is inspired by REBOL (Carl Sassenrath, 1997), where word: is an atomic set-word — the colon is fused onto the word itself. Axioma adopts that look but treats : as an ordinary binding operator (its own token), so even x : 5 — with a space — still binds. (REBOL itself drew on Lisp, Forth, Logo and Self; the set-word notation is its own — Algol and Smalltalk used :=, Logo used make.)

: creates a binding; = reassigns an existing one — and the difference is enforced. Use = on a name you never declared and Axioma stops you, telling you to declare it with : first. Comparison for equality is a third thing again: ==.

You can also bind several names at once, left-to-right.

bindings.axOpen in Playground ↗

Words, types & introspection

A subtlety worth naming: x: 56 doesn't declare a variable in the C sense — it binds a word. First-class words long predate REBOL: Forth is built entirely on words (its dictionary maps each word to code), and Logo treats the word as a primitive datatype — Logo even fetched a word's value with :x, the very get-word Axioma still uses. Axioma inherits that lineage through REBOL (and Lisp's first-class symbols sit underneath it). A bare word like x evaluates to its value; :x gets that value; 'x is the word itself, an unevaluated literal of type Word (the ' quote is Lisp's). The word is just a name in a binding table, so it can hold a value of any type.

words.axOpen in Playground ↗

That last clause — any type — matters: every value has a type. Ask for it with the @ sigil or the type function; the names match the built-in type-concepts, so @5, type(5) and 5 is Integer all agree. And @ reaches past values: aim it at a bare keyword or operator and it reports that token's category@if is a control_flow_keyword, @+ an arithmetic_operator.

types.axOpen in Playground ↗

The everyday value types are Integer, Float, String, Boolean, Array, Set, Tuple and ObjectMap (a hash) — with many more for the reasoning machinery. You can also declare your own closed set of named values, an enum, with enumerates: each member is a real value you can order with .ord and count with len.

The language also documents itself. Write doc followed by any word — doc why, doc map — and Axioma prints its built-in reference for that word, in a script or the REPL.

Your own words — aliases

If words are first-class, the natural next step is to add your own. alias new = original gives any keyword, builtin, or word a second name — so the surface can read the way you think, or skin a small domain language. It's the focused version of a tradition Lisp and Forth are built on — programs that grow the language by defining new words. Here an alias is a synonym, woven in as the source is read, so define it before you use it.

alias.axOpen in Playground ↗

An alias is additive — it adds a fresh word; it can't shadow a word that already exists, so the new name must be unused (ask for alias repeat = while and Axioma tells you repeat is already taken). And aliases aren't only for keywords — aim one at a builtin, or at a function you wrote. Drop it again with unalias name.

alias-words.axOpen in Playground ↗

Where : binds now, declare binds lazily — the expression is captured and only computed on first use, so it can even refer to names defined later.

LESSON 3

Blocks — the versatile [ ]

Square brackets are the most versatile punctuation in Axioma. At heart, [ ] is a block — a sequence of steps whose value is its last expression. That single idea powers a remarkable range of the language:

How does Axioma tell an array from a block? By context and content. In a body — a function or a control-flow branch — the brackets are always a block, yielding the last value (so if … then ["big"] else ["small"] gives the string "big", not a one-element array). Standing on their own, brackets of bare values are an array, while brackets that contain statements — like the bindings below — are a value-block.

value-block.axOpen in Playground ↗

That same block is the body of control flow — a loop runs a block per iteration, and an if (an expression) hands back the value of whichever branch it takes:

bodies.axOpen in Playground ↗
LESSON 4

Functions

A function is just a value — you bind it with : like anything else, and its body is a [ ] block. Call it with parentheses.

square.axOpen in Playground ↗

There's an optional named form, and a lightweight lambda … => for short functions:

forms.axOpen in Playground ↗

Functions can call themselves (recursion), and can return other functions that capture their surrounding scope (closures):

recursion.axOpen in Playground ↗
closure.axOpen in Playground ↗

Functions and operators are interchangeable values, so the same arithmetic reads three ways: infix is the default, prefix treats any operator as a function you can pass around, and a Forth/Pop-11 stack gives postfix / RPN-style computation.

notation.axOpen in Playground ↗
stack.axOpen in Playground ↗
LESSON 5

Composition — functions over collections

Functions are first-class, so you pass them around. map applies one to every item; filter keeps what matches; reduce folds a collection to a single value.

And because a function is a value, you can compose small ones into a pipeline:

compose.axOpen in Playground ↗
LESSON 6

Sets, arrays & comprehensions

Sets and comprehensions sit at the centre of Axioma — a great deal of the language reads like the set-builder notation from a maths text, and runs. But it all rests on one distinction worth getting straight first: the difference between an array and a set.

Arrays and sets — order vs uniqueness

An array [ ] is an ordered sequence: it keeps elements in the order you wrote them, keeps duplicates, and you reach one by position — Axioma indexes from 1. A set { } is an unordered collection of unique values: duplicates collapse, there are no positions to index, and because a set has no intrinsic order Axioma may print its members in any order — so never rely on it. You don't ask a set “what's at position 1?”; you ask “is this in it?”.

arrays-and-sets.axOpen in Playground ↗

Ranges — generate a sequence

You rarely write a long sequence by hand. A range generates one with the .. operator, inclusive of both ends — and the bracket you choose decides the kind: [1..6] is an ordered Array, while the bare 1..6 is a Set. Add a step with a third segment ([0..10..2]), count downward by giving a larger start ([5..1]), and range over characters as well as integers. The range(...) function is the same generator in call form.

ranges.axOpen in Playground ↗

Ranges are the natural source for everything in this lesson — feed one to a comprehension or a collection function and the sequence streams straight in:

ranges-use.axOpen in Playground ↗

The algebra of sets

Because a set is a mathematical object, the whole algebra is built in: membership and its negation , union , intersection , difference \, symmetric difference (the members in exactly one set — and work too), cardinality with len, and an equality that ignores order. The subset relations come in two strengths: / allow equality, while / are proper — strict, and so false when the two sets are equal. If your keyboard lacks the glyphs, most have a word form too — in, union, intersect, difference, symdiff.

set-algebra.axOpen in Playground ↗

Can't type the glyph? Ask Axioma

Since these symbols are hard to type, the language carries a catalog of its own glyphs. symbols() lists them (optionally by category), and glyph(name) fetches one by its Axioma name, its LaTeX name, a Greek letter, an emoji name, or a raw U+… codepoint — so you never need the special key. Each result is a first-class Glyph that prints as the character, compares equal to its string, and carries .name / .meaning / .codepoint. (In the REPL, :symbols prints the table and :doc ∪ explains one.)

glyph-catalog.axOpen in Playground ↗

Comprehensions — set-builder notation

A comprehension builds a collection by describing it. Read { x | x <- xs, cond } exactly as the maths: “the set of x drawn from xs such that cond.” The part before the bar can transform each element; every comma-separated condition after it must hold — they combine with and. (mod is the word form of %.)

set-builder.axOpen in Playground ↗

List comprehensions — same notation, ordered result

Swap the braces for brackets and the same notation yields an array — so the result keeps its order and its duplicates. Either form can draw from more than one source at once; several generators produce every combination (a Cartesian product).

list-comprehension.axOpen in Playground ↗

Python's spelling, and dict comprehensions

Axioma is a superset of Python's comprehension syntax, so the pipe-less for … if … form pastes in unchanged. And a comprehension whose head is a key: value pair builds a hash (a dict) instead of a set.

python-and-dict.axOpen in Playground ↗

Query clauses, and lazy streams

Comprehensions also carry the SQL-style clauses orderby, limit and offset for shaping a result. And wrapping a comprehension in parentheses makes it lazy — a stream computed on demand, so you can pull a handful of values from a source of a million without ever building the whole thing.

query-and-lazy.axOpen in Playground ↗
LESSON 7

Quantifiers — logic that evaluates

The universal and existential quantifiers range over a set and evaluate to a truth value. Write them as words…

quantifiers.axOpen in Playground ↗

…or as the symbols mathematicians actually write — the same AST either way:

glyphs.axOpen in Playground ↗
LESSON 8

Logic & rules

Declare a relation, assert some facts, and write rules with <== (“holds when”). Rules can be recursive — here the engine computes the full transitive closure of a graph, Datalog-style, iterating to a fixpoint.

paths.axOpen in Playground ↗

Rules come in a 2×2: strict (<== / ==>) vs defeasible (<~~ / ~~>), and backward (head <op> body) vs forward (body <op> head). Strict rules derive theorems; defeasible ones hold by default and derive conjectures — and the grade is recorded on every conclusion.

rules.axOpen in Playground ↗

Abduction runs inference backwards: given something observed, abduce proposes the best explanation a rule could supply — Peirce's "inference to the best explanation," built in (the cognitive kernel also has understand and examine).

abduce.axOpen in Playground ↗
LESSON 9

Concepts & the copula is

A concept starts as a class but is more than one — it can also carry actions, a defining boundary, and an epistemic grounding (the overview goes deeper). The everyday parts: declare fields with has (several at once), make an instance with the indefinite article a / an, and classify with Russell's copula is — which Axioma keeps precise: membership () for an instance, class-inclusion () between two concepts.

concepts.axOpen in Playground ↗

Subclass with extends, and give a concept behaviour with an action — a method whose body sees the receiving instance as it. Actions are inherited down the extends chain and can be overridden.

concept-actions.axOpen in Playground ↗
LESSON 10

Beyond true and false

Real knowledge is sometimes missing and sometimes contradictory. Axioma builds that in: Belnap's four-valued logic has a value for “asserted and denied” (⊤⊥), and Kleene's three-valued logic handles the unknown (om) without collapsing.

truth.axOpen in Playground ↗

Belnap's four values form a bilattice — ordered two ways at once: by truth (false → true) and by information (neither → both). Contradiction (⊤⊥) doesn't crash; it propagates through the operators.

belnap.axOpen in Playground ↗

Truth is only one axis. A single fact carries orthogonal axes at once — its Belnap truth, its epistemic grounding (Lesson 8), and its kind (empirical, logical, …) — each set and queried independently.

LESSON 11

Refinements — one word, adapted

A refinement is a /word suffix that adapts a keyword or operator instead of inventing a new one — REBOL's idea, carried into Axioma's meaning. The copula is the clearest case: bare is tests class membership (), while is/same tests identity (= — the very same entity, not just an equal one).

refinements.axOpen in Playground ↗

The same /word dialect tunes a fact's lifecycle: /persist writes it to the knowledge base, /transient keeps it to this session. And it composes with epistemic grade — axiom/transient is still graded axiom, just not saved to disk.

refinement-lifecycle.axOpen in Playground ↗
LESSON 12

Code is data — metaprogramming

Axioma is homoiconic: programs are data you can build, inspect and run. parse turns a string into an AST, quote captures code unevaluated, do runs an AST, and a macro rewrites code before it executes.

code-as-data.axOpen in Playground ↗

The *form family renders any expression for inspection — fullform as a Mathematica-style string, treeform as a tree, and tableform a relation's extent as a table.

introspect.axOpen in Playground ↗
tableform.axOpen in Playground ↗

A binary relation is also a graph: graphform renders it as ASCII, as a Sowa conceptual graph, or as Graphviz DOT you can paste into any renderer.

graphs.axOpen in Playground ↗
LESSON 13

Meaning & natural language

Axioma can model meaning directly. A cognitive word carries Wierzbicka's NSM semantic primes and a Schank Conceptual-Dependency act — the building blocks linguists use to decompose meaning.

cognitive.axOpen in Playground ↗

Relations can label each place with a semantic role — Lojban's selbri place structure, lifted into the language. Natural-language dialects like <<Lojban| … >> and cross-language translate build on the same idea (translation needs an AI provider, so it runs in the desktop CLI rather than this in-browser sandbox).

selbri.axOpen in Playground ↗
LESSON 14

Pattern matching

ML- and Rust-style match … with tries each arm top-to-bottom. A when clause adds a guard; _ catches everything else. match is an expression — it yields the value of the first arm that fits.

match.axOpen in Playground ↗

match is total by construction: when nothing matches and there is no _, it returns om (the undefined value) rather than crashing — so a partial match stays recoverable.

total.axOpen in Playground ↗
LESSON 15

Errors are values

Axioma has no exceptions and no stack unwinding. try(expr) runs the expression and hands back any fault as an ordinary, inspectable value — which auto-classifies into a concept like DivByZero, TypeError or IndexError, so you can branch on it with the same is copula you use everywhere else.

otherwise is the railway operator: if the left side faults, take the right instead.

otherwise.axOpen in Playground ↗
LESSON 16

Strings & text

${…} interpolates any expression straight into a string — names, arithmetic, calls.

interp.axOpen in Playground ↗

\u{…} escapes reach the entire Unicode range — handy for the mathematical symbols Axioma reads natively — and chr/ord convert between a character and its codepoint.

unicode.axOpen in Playground ↗
LESSON 17

Stacks & loops

Axioma carries a Forth / Pop-11 heritage: a first-class stack with push, pop, peek, dup, swap and depth.

stack.axOpen in Playground ↗

And when a loop is the clearest tool, the imperative forms are there: while, repeat … until, and foreach.

loops.axOpen in Playground ↗

That's the core.

You've met bindings, blocks, functions, sets, logic, concepts, many-valued truth, refinements, metaprogramming and natural-language meaning — enough to read most Axioma. Take any example into the full playground and keep going.

The full Axioma Manual and textbook are coming to the site — this tutorial is the slimmed-down tour.