← Back to MeTTa Programming Language
Responsible: Alexey Potapov, Vitaly Bogdanov (Hyperon Experimental); Patrick Hammer (PeTTa); Greg Meredith (MeTTaTron, Meta-MeTTa)
Papers: Potapov (2021), MeTTa Specification; Meredith, Goertzel, Warrell, Vandervorst (2023), Meta-MeTTa: an operational semantics for MeTTa; Goertzel (2025), Hyperon Whitepaper §3
Status: Current. MeTTa is operational across multiple implementations: Hyperon Experimental (reference, Rust), PeTTa (high-performance, Prolog), JeTTa (JVM, Kotlin), MeTTa-Morph (Scheme). The MeTTa-4 semantic model and MeTTa-IL compilation pipeline are under development. PyMeTTa (Python transpilation layer) is proposed.
This card provides technical depth beyond the concise MeTTa index card. MeTTa (Meta-Type Talk) is Hyperon's native "language of thought" — a homoiconic, gradually-typed programming language designed specifically for AGI. It unifies functional programming, logic programming, and dependent typing into a single formalism that operates directly over AtomSpace as graph transformations.
Atoms, expressions, gradual typing, type-directed evaluation, pattern matching, equalities, and non-deterministic evaluation.
The basic elements of MeTTa are symbols (distinguished by name, optionally grounded to external data or code). Symbols compose into expressions representable as trees or, with deduplication, as metagraphs. Expressions are stored in an AtomSpace container equipped with pattern matching. There is no distinction between code and data — MeTTa programs are expressions in AtomSpace, queryable and rewritable by other programs.
MeTTa uses gradual typing: untyped symbols receive the special type ?, which is treated as functional (so expressions starting with untyped symbols are interpreted as function applications, not tuples). The arrow type (\(\to\)) describes function signatures with arbitrary arity; dependent types are supported naturally (e.g., (: Mortal (→ Human Type)) creates a dependent type indexed by Human values). Type constructors are not separate syntax — any typed symbol acts as a constructor of its type, allowing new knowledge base entries to be inserted modularly at runtime. Currying is not automatic and must be performed explicitly. Grounded types are registered via regex patterns paired with constructor functions, allowing the parser to recognize and wrap external data (e.g., floats, strings) transparently.
MeTTa's evaluation model is type-directed: expressions whose first element has an arrow type are treated as function applications (subexpressions evaluated, then the grounded function executed or equality query formed); expressions whose head has a non-arrow type are treated as tuples and evaluate to themselves. This two-rule dispatch — arrow-typed head → application, otherwise → tuple — is the core mechanism replacing traditional function-call syntax.
AtomSpace's pattern matcher extracts expressions matching a query via unification of variables (prefixed with $). Binding is asymmetric: query variable bindings are prioritized over expression variable bindings, and binding a variable to a non-variable symbol takes precedence over binding to another variable. The same variable appearing multiple times must bind to the same subexpression. Conjunctive queries use comma-joined patterns with shared variables that must be satisfied simultaneously. The pattern matcher is type-aware — type annotations are treated as expression enrichments (supplementary metadata, not structural modifications), meaning (e (: a A)) matches (e a) and the type information propagates without altering the expression structure. This enrichment model extends naturally to vector embeddings and attention values.
The built-in = symbol defines directed rewrite rules: (= a b) means a can be transformed to b during evaluation, but not vice versa. This directionality enables MeTTa to express causal generative models — directed paths in expression space rather than symmetric equivalences. Pattern matching against equality definitions can produce conditional matches requiring further unification, which the interpreter resolves by constructing chained equality queries. Type-level equalities (e.g., (= (TCons $a (List $a)) (List $a))) are processed the same way, enabling type computation at runtime.
MeTTa evaluation proceeds by matching expressions against rewrite rules and replacing them with the rule body under the computed substitution. The interpreter maintains a local AtomSpace as an evaluation queue, processing one expression at a time (though concurrent evaluation of multiple targets is supported). Multiple equality matches produce multiple evaluation branches — MeTTa is inherently non-deterministic. Because equalities are not required to be unique (the same left-hand side can have multiple right-hand sides), functions can naturally express non-deterministic choice. This enables direct encoding of search problems: the Specification demonstrates a subset-sum solver using non-deterministic binary list generation and compositional evaluation. Non-total functions are permitted by default — an expression with no matching equality evaluates to itself, acting simultaneously as a type constructor and a partial function.
The reference implementation defines a formal EBNF grammar for MeTTa syntax. Programs are sequences of atoms, optionally prefixed by ! (evaluate and return result to user; unprefixed atoms are added to the AtomSpace). The grammar distinguishes four atom kinds — Symbol (WORD tokens), Variable ($-prefixed), Grounded (WORD or STRING matched by tokenizer regex patterns), and Expression (()-delimited lists). Grounded atoms are constructed via a tokenizer — a collection of (regex, constructor) pairs that intercept matching tokens during parsing (e.g., [0-9]+ → integer parser).
Seven elementary types are built in: Type (type of types), %Undefined% (unknown type), Atom (supertype matching any atom), and four meta-types corresponding to the grammar: Symbol, Variable, Expression, Grounded. Meta-types control evaluation order — an argument typed as Atom or a meta-type is passed unevaluated to the function.
Three special result atoms have built-in semantics: Empty (branch produces no result — removed from output), NotReducible (expression cannot be reduced further — returned as-is), and Error (with structured subtypes: StackOverflow, NoReturn, IncorrectNumberOfArguments, BadArgType, BadType). The distinction between Empty and NotReducible is critical: Empty prunes a non-deterministic branch, while NotReducible preserves the expression as a valid data term.
(Provenance: repo-doc, hyperon-experimental docs — MeTTa language specification)
The interpreter evaluates atoms via the metta(atom, type, space, bindings) entry point, dispatching on the atom's meta-type:
BadType error otherwise.Function evaluation uses metta_call, which either invokes a grounded function's native code or queries the AtomSpace for (= call_expr $X) equality rules and recursively evaluates the matched results. Non-determinism arises naturally: multiple equality matches produce multiple evaluation branches, each pursued independently. The interpreter filters error branches when at least one success branch exists, but returns all errors if no branch succeeds.
Pattern matching uses two-sided unification via match_atoms. Variable bindings track both value assignments (\(\text{var} \leftarrow \text{value}\)) and equality relations (\(\text{var}_1 = \text{var}_2\)). Binding merges can produce multiple results when previously bound variables are matched against new patterns, and loop bindings (circular references) are automatically filtered out.
(Provenance: repo-doc, hyperon-experimental docs — MeTTa language specification)
The Meta-MeTTa four-register state machine \(\langle i, k, w, o \rangle\), bisimulation, ρ-calculus compilation, resource-bounded semantics, and MeTTa-4.
The Meta-MeTTa paper provides a formal operational semantics following the standard pattern: an algebra of states (monad), a structural congruence (algebra of the monad), and rewrite rules (state transitions). MeTTa's execution state is a four-register tuple \(\langle i, k, w, o \rangle\):
Six named rewrite rules define all state transitions:
The guard insensitive(t, k) — meaning no unifiable equality rule exists for term \(t\) in knowledge base \(k\) — is the termination condition that moves results to output. Terms in the grammar include lists (ordered), multisets (unordered, with {...} syntax imposing commutativity), and comprehensions (intensionally defined collections that generalize let/letrec to streams and remote data). Bindings come in three modes: linear (\(\leftarrow\), consuming), repeated (\(\Leftarrow\), non-consuming), and peek (\(\leftharpoonup\), read-only).
The operational semantics recovers a notion of barbed bisimulation adapted from the asynchronous \(\pi\)-calculus: queries in the input register serve as barbs (observable actions). Two MeTTa computations are bisimilar if they produce the same observable behavior at the input/output boundary, regardless of internal workspace transitions. This provides a formal criterion for proving that independent implementations are correct: any compliant MeTTa client must be bisimilar to the specification. The paper demonstrates this by proving that the compilation from MeTTa to the \(\rho\)-calculus preserves bisimulation (Theorem 1: \(S_1 \approx S_2 \Leftrightarrow [\![S_1]\!]_M \approx [\![S_2]\!]_M\)), establishing that MeTTa programs compiled to Rholang behave identically to their source semantics.
MeTTa's concurrency model is grounded in the reflective higher-order \(\rho\)-calculus, which treats programs as asynchronous processes communicating over channels. This enables parallelized execution without blocking, where names are quoted processes (\(@\mathrm{Term}\)) and processes can introspect their own structure via dereference (\(*\mathrm{Name}\)). The compilation to Rholang (\(\rho\)-calculus implementation language) provides the bridge to ASI Chain's secure decentralized execution.
Meta-MeTTa §6 extends the four-register state to a five-register model \(\langle i, k, w, o; eos \rangle\) where \(eos\) tracks effort objects (EOs) — computational resource tokens analogous to Ethereum's gas. Each rewrite rule is reprised with resource bounds: transitions are permitted only when sufficient EOs remain, and each operation deducts a cost determined by a polymorphic cost function \(\#\). This enables MeTTa execution on decentralized networks where denial-of-service protection requires metered computation. A second correctness theorem (Theorem 2) proves that the resource-bounded compilation to Rholang also preserves bisimulation.
The whitepaper describes MeTTa-4 as the target semantic model providing clean small-step operational semantics aligned with surface syntax. Core features: committed choice by default, delimited nondeterminism via explicit operators, atomic Space operations via the for construct with transactional semantics.
The reference implementation defines a minimal instruction set — an "assembly language for MeTTa" — sufficient to implement the full MeTTa interpreter in MeTTa itself. Minimal MeTTa uses normal evaluation order (arguments passed unevaluated) and comprises 8 core operations:
(eval <atom>) — One step of evaluation: for pure MeTTa, searches (= <atom> $X) in the AtomSpace and returns all matches; for grounded atoms, calls the foreign function. Returns NotReducible if no match found.(chain <atom> <var> <template>) — Evaluate <atom>, then substitute all occurrences of <var> in <template> with each result. This is the mechanism for controlling evaluation order in a normal-order language.(function <body>) / (return <atom>) — Evaluate <body> in a loop until (return <atom>) is reached, providing function abstraction with explicit termination. Returns (Error NoReturn) if evaluation ends without a return.(unify <atom> <pattern> <then> <else>) — Pattern-matching conditional: returns <then> with merged bindings on match, <else> otherwise.(cons-atom <head> <tail>) / (decons-atom <expr>) — Expression construction and deconstruction (head/tail operations).(collapse-bind <atom>) — Collect all non-deterministic evaluation results into a single expression with their bindings (inference control).(superpose-bind ...) — Complement of collapse-bind: inject filtered results back into the evaluation plan.Additional instructions include (metta <atom> <type> <space>) for invoking the full interpreter within MeTTa, (evalc <atom> <space>) for evaluation in a specified context space, and (context-space) for accessing the current working space.
The minimal instruction set is Turing complete, demonstrated by a full Turing machine implementation in minimal MeTTa: tape representation as ($head $hole $tail), state transitions via pattern matching on ($rule $state $char), and head movement via cons-atom/decons-atom operations on the tape structure. The machine halts when the state matches HALT. Each minimal instruction is a total function — partiality is expressed through Empty (branch elimination).
The HE reference interpreter is itself written in minimal MeTTa, with performance-critical paths implemented as Rust functions injected via (call-native ...). The metta operation bridges both levels: it analyzes the input atom and returns an execution plan in minimal MeTTa that includes Rust-backed steps.
The Meta-MeTTa operational semantics (MOPS) and the minimal instruction set offer complementary formalizations. MOPS' Query and Chain rewrite rules correspond to minimal MeTTa's eval. MOPS' Transform corresponds to unify. Minimal MeTTa's chain instruction has no direct MOPS analogue — it provides explicit sequencing absent from the more declarative MOPS model. Where MOPS provides the mathematical foundation for bisimulation proofs, the minimal instruction set provides the concrete implementable substrate.
(Provenance: repo-doc, hyperon-experimental docs — minimal MeTTa specification; publication, Meredith et al. 2023)
Multi-layer compilation stack (MeTTa → MeTTa-IL → MORKL/MM2), system interfaces, and all seven implementation anchors.
MeTTa sits within a multi-layer compilation stack described in the whitepaper (§3):
foreign-safe-lambda, enabling integration with existing high-performance codebases. The compile! API allows in-session compilation from files, strings, or tuples.efee4be (2026-01-19, Cargo v0.2.0, 190 commits ahead of the v0.2.0 Git tag), the repo name "MeTTa-Compiler" overstates current capability: the compile function parses tree-sitter output into a MettaState AST without code generation, and execution is an iterative trampoline tree-walk interpreter (compilation tracks live on unmerged feature branches feature/wam-backend, feature/jit-compiler, pr17/bytecode-vm, pr20/jit-codegen). Performance optimizations include 242.9× type lookup speedup (lazy cached subtrie), 10.3× fact insertion speedup (direct byte conversion bypassing string serialization), and indexed rule lookup (1.6–1.8×). Commit 9d7ea4b (2025-12-29) replaced PathMap-based multiset set operations (union-atom, intersection-atom, subtraction-atom, unique-atom) with HashMap-based ones, with empirical 3.5–5.3× speedup across dataset sizes 10–100,000; PathMap is retained for rule/fact/atom/type storage and MORK pattern-match queries. Rule matching filters to MOST-SPECIFIC rules only (src/backend/eval/mod.rs:1023+), suppressing catchall rules when a more-specific rule matches — a documented divergence from the hyperon-experimental v0.2.10 multi-reduction semantic. Provides synchronous and asynchronous Rholang integration via direct Rust linking (no FFI) through the shared f1r3node/models protobuf types. Targets MeTTa-IL for ASI Chain execution. (MeTTa runtime cluster pilot Source 3, closed 2026-05-13.)MeTTa's module system (Hyperon Experimental) encapsulates execution contexts: each module has a unique Space and Tokenizer, with the &self token resolving to the module's own Space. Modules form a hierarchical namespace using : as separator (e.g., top:mod1:sub_a), where top is always the root module. The same loaded module instance can appear at multiple points in the hierarchy via aliasing.
Three import modes are supported:
import module as name — Import entire module under an aliasimport * from module — Import all symbols into the current Spaceimport item from module as name — Import specific itemsModule name resolution follows a priority chain: (1) already-loaded modules in the current context, (2) explicit entries in the module's PkgInfo (version requirements, file paths, remote URLs), (3) registered Catalogs searched in priority order. Default catalog search paths include the module's own resource directory, the hyperon/exts/ directory (Python environment), and an OS-specific config directory. Modules can be loaded from single .metta files, directories containing a module.metta file, or Python modules (.py files or packages with __init__.py). The PkgInfo structure (analogous to Cargo.toml) specifies metadata and dependency requirements. Export visibility and cross-module tokenizer import semantics are still under development.
(Provenance: repo-doc, hyperon-experimental docs — module system developer guide)
Current implementation status, recent capabilities, open research directions, and primary sources.
Recent PeTTa capabilities (transcript-backed, Feb–Apr 2026):
qsave_program. Enables interrupting and resuming long-running computations with atomic double-buffering (commit/commit.new pattern) to survive power outages. Directly connected to ASI Chain node execution — serialized continuations are the mechanism for checkpointing MeTTa computations on decentralized nodes. (Patrick Hammer, MeTTa Study Group, Feb 2026)Related cards: AtomSpace · MORK · ASI Chain Full · Meta-MeTTa Paper map