Introduction
Hello, CX
CX is one language for **data** and **code**. The same brackets, the same sigils, the same evaluator. You don't pick a templating engine for output, a query language for selection, or a config dialect for deployment — there is one shape, and you write everything in it.
[hello greeting='world']
That is a complete CX document. It is also a complete CX program when passed to the evaluator — it evaluates to itself. CX is **homoiconic**: programs are data; data round-trips through every supported surface (JSON, YAML, TOML, XML, Markdown); identity is the SHA-256 of the canonical bytes.
Here is one screen of CX that exercises every category covered later in this guide — data, code, selection, update, and output:
[# 1. Data: a small document
#]
[users
[user id=1 email='ada@example.com' active=true]
[user id=2 email='grace@example.com' active=false]
[user id=3 email='linus@example.com' active=true]]
[# 2. Code: select active users with CXPath
#]
[?for [in $u //user[= $_@active true]] [yield
[active-user email=$u@email]]]
[# 3. Pure-functional update: mark one user verified
#]
[?modify $doc //user[= $_@id 1]/@status [set 'verified']]
Three forms, one language. No string concatenation; no AST mismatch between selectors and templates; no separate type system for queries. The full vocabulary is detailed in data and code; this section is just the elevator pitch.
Design philosophy
CX is built on six commitments. Every design choice in the rest of this guide — and every choice deliberately deferred — falls out of one of them.
**1. Data and code share one syntax.** A directive like `[?for]` is spelled the same way as a data element like `[user]`. There is no "template language" embedded inside a "data language". A program is a document; a document is potentially a program. Tooling — parser, lexer, AST, tree-sitter grammar, LSP — is shared end-to-end.
**2. Every projection round-trips.** CX has a canonical surface (the bracket form) and projections for JSON, YAML, TOML, XML, and Markdown. Every projection is lossless in the round-trip sense: CX → JSON → CX produces byte-identical canonical bytes. The normative round-trip rules live in surfaces and in [`spec/canonical.md`](../../spec/canonical.md).
**3. Pure-functional updates.** There is no in-place mutation in CX. The `[?modify]` directive (see modify) takes a document and a CXPath focus, and returns a **new** document. Unchanged branches share structure with the original (the standard persistent-tree technique). Concurrency is safe by construction — no reader ever observes a half-modified tree.
**4. Identity via canonical bytes plus SHA-256.** Two CX documents are equal iff their canonical bytes are equal, and the document's identifier is the SHA-256 of those bytes. This makes caching, deduplication, content-addressable storage, and cross-language equality checks trivially correct. See identity.
**5. One selector vocabulary everywhere.** CXPath is **the** way to point at things — for reading (`select_all`), for iteration (`[?for]`), for type-tests in `[?match]`, and for update focus in `[?modify]`. It aligns with XPath 3.1 (see [`spec/cxpath_alignment.md`](../../spec/cxpath_alignment.md)) so that developers coming from the XML ecosystem feel at home, with deliberate divergences to keep it safe and CX-shaped.
**6. Orthogonality — one rule, no exceptions.** CX has exactly one syntactic form: `[head …]`. Calls, operators, directives, and data elements are all that one shape, distinguished only by the head. There is no statement/expression divide, no infix, no special slots, and no keyword the grammar treats as a privileged exception. Even the constructs other languages hard-code — `if`, `lambda`, `quote`, `for` — are in CX ordinary forms obeying the same rule. Read it like XML, program it like Lisp; CX is more uniform than either, because in CX the surface *is* the rule. And the discipline extends from syntax to features: every feature must apply uniformly across its natural domain or carry a written, justified exception — enforced by the UNIFORM review gate in [`spec/process/spec-authoring-guide.md`](../../spec/process/spec-authoring-guide.md) §3, not merely aspired to.
**Orthogonality in context.** Orthogonality is the *uniform application of a small rule set* — features compose without special cases. It is not the same as simplicity: a language can be small yet riddled with privileged built-ins user code cannot reproduce, or large yet principled. The table below ranks CX against the languages CX binds to, plus Lisp-1 and Scala, on this one axis. It is illustrative, not a leaderboard — and orthogonality is only one axis. Where CX trades it away (ecosystem maturity, library breadth) is the honest accounting in comparison.
| language | tier | why |
|---|---|---|
| CX | Reference | One grammar production; every construct is the same [head …] form. No statement/expression split, no infix, no privileged keyword — even special forms obey the one rule. |
| Lisp-1 (Scheme) | Near-reference | Homoiconic S-expressions; single namespace (more uniform than Lisp-2). Loses only because quote, lambda and if are privileged special forms — CX folds even those into the one rule. |
| Scala | High (uniform model) | Everything is an expression; functions are objects; operators are methods; uniform access. Diluted by a large sugary surface — implicits/givens, two dialects. |
| Ruby | High (uniform model) | Smalltalk lineage — everything is an object, everything a message send, operators are methods. Uniform core, non-uniform surface (blocks vs procs vs lambdas, many sugars). |
| V | Moderate | Deliberately minimal, one canonical way to do things. Orthogonality by austerity; still carries privileged built-ins and a partial statement/expression split. |
| Kotlin | Moderate | Expression-oriented (if, when, try are expressions); operators by convention. Primitives-as-objects is a JVM fiction; much surface exists for Java interop. |
| Python | Moderate | Real uniformity via the dunder protocol; but a hard statement/expression wall — def, class and import are statements, lambda is crippled. |
| Swift | Moderate | Genuine protocol-oriented uniformity, but a special-case-dense surface — optionals, guard, defer, property wrappers, result builders. |
| Rust | Low–moderate | Expression-oriented core, but a federation of subsystems with their own rules — ownership, lifetimes, traits plus coherence, a separate macro grammar, async, unsafe. Powerful is not orthogonal. |
| C# | Low | Multi-paradigm, accreted over many versions — LINQ, async, properties, events, pattern matching each a distinct syntax. Statement/expression divide. |
| Java | Low | The classic wart — primitives vs objects — plus special-cased arrays, no operator overloading, erasure generics, statement-heavy ceremony. |
| Go | Low | Simple but not orthogonal — magic built-ins user code cannot replicate (make, append, len, cap, delete), special slice/map/channel semantics, retrofitted generics, error-by-convention. |
| TypeScript / JavaScript | Lowest | Most accreted — this-rebinding, hoisting, prototype vs class, == vs ===; TypeScript layers an entire erased second language over the runtime. |
**Two distinctions drive the ranking.** *Simplicity vs orthogonality*: Go and V are simple, but Go is not orthogonal — its magic built-ins are unreproducible by user code. *Uniform model vs uniform surface*: Scala and Ruby have uniform semantic cores but large sugary surfaces; CX is the only entry whose surface itself is the single rule, because it is homoiconic (see homoiconicity) — there is no gap between model and syntax for uniformity to fall out of.
How to read this guide
This guide is the developer-facing reference for CX. Read it linearly the first time. After that, sections are independent enough to use as topic-specific reference.
The flow is data → surfaces → identity → analytics → code → bindings → tooling → concepts → migration. Each section calls out the normative spec documents under `spec/*.md` rather than restating them; if you need the formal grammar, error matrix, or wire-format details, the guide points you there. Front-matter (quickstart) and back-matter (glossary / faq / comparison) flank the numbered sequence.
- data — the data language: lexical structure, scalars, collections, sigils, prose, typed columnar tables, schema language, includes. Start here if you've never seen CX.
- surfaces — the canonical CX form and its JSON / YAML / TOML / XML / Markdown projections, plus the round-trip contract.
- identity — canonical bytes, SHA-256 hashing, the ast-bin and data-bin binary wire formats, ID/IDREF scoping, capability bits, FFI lifetime.
- analytics — the columnar / streaming binary surface: :table data shape, CXCol format, Arrow zero-copy bridge, Parquet read/write, ecosystem integrations (DuckDB / Polars / pandas / DataFusion / Spark).
- code — the CX code language: the 40 directives, CXPath, patterns, bindings, the six core constructs, builtins, errors-as-values, services / workers / async, resilience.
- bindings — the C ABI, Layer 1 canonical method set, Layer 2 host idiom packs, and per-language quickstarts for V, Python, Go, and Rust.
- tooling — LSP, tree-sitter, VS Code, Neovim, Helix, `make docs`, the playground.
- concepts — pure-functional updates, structural sharing, capability bits, error-code namespace, ABI versioning, governance.
- migration — upgrade guide: renames, retired surfaces, the automated migration script, the archived binding set.
**Conventions used throughout.** Code blocks marked `:lang cx` are literal CX (data or code; the same shape). Code blocks marked `:lang python`, `:lang go`, `:lang rust`, `:lang v` are host-language binding code. Cross-references to other sections use `[[anchor]]`. References to spec documents use ordinary markdown links.
The normative grammar lives in [`spec/grammar.ebnf`](../../spec/grammar.ebnf); the directive registry (39 entries) is in [`spec/code.md`](../../spec/code.md) §4.1; the C ABI surface is in [`spec/abi.md`](../../spec/abi.md). This guide is curated learning + reference path, not a replacement for those documents.