Grammar

Orthogonal Grammar Composition

Read this when you are tempted to split AEON into separate mini-languages.

AEON's grammar is intentionally orthogonal. The same few components reappear in different positions instead of being confined to one special feature.

For an AI system, the practical rule is: do not treat nodes, attributes, types, anonymous children, objects, lists, tuples, and references as isolated modes with unrelated rules. Treat them as composable grammar surfaces that preserve claims until a trusted consumer interprets them.

Orthogonality

Orthogonal means composable, not universal.

Orthogonal grammar composition means a feature can combine with other features through shared rules instead of requiring a special syntax rule for every combination.

AEON prefers a small set of composable grammar primitives over a large collection of special-purpose constructs. Rather than introducing a new syntax for every scenario, existing grammar surfaces are reused where the context permits them.

key:type = value
key@{meta:string = "value"} = value
key@{meta:string = "value"}:type = value
@{meta:string = "value"}:type = value
<tag@{meta:string = "value"}:type(...)>

Orthogonal composition does not imply universal composition. Grammar surfaces compose consistently, but each context still defines what is syntactically valid.

Core Model

Think in heads and values.

Most visible AEON structure can be understood as a head plus a value. The head carries identity, local metadata, and a datatype claim. The value carries the thing being bound, nested, referenced, or ordered.

Head means the syntactic surface that carries identity, attributes, and datatype claims. Value means the payload associated with that head.

named binding head       key@{attributes}:type = value
attribute entry head     key@{attributes}:type = value
anonymous child head     @{attributes}:type = value
node head                <tag@{attributes}:type(...)>

These are not identical contexts, but they share the same composition idea: optional attributes, optional datatype claim, then a value or child list where that context permits it.

Attributes

Attributes are not node-only metadata.

A common mistake is to import an XML or HTML mental model and assume attributes belong only to nodes. In AEON, attributes are a general binding-head feature and a node-head feature.

width@{unit:string = "cm"}:number = 33

contact@{source:string = "crm"}:object = {
  name:string = "Bob"
}

values:list = [
  @{unit:string = "cm"}:number = 3
]

html:node =
  <div@{id:string = "message", class:string = "greeting"}("Hello")>

In all four examples, the attribute block is local side information attached to the binding head, anonymous child head, or node head. It is not a postfix operation on an already-finished value.

Attribute Entries

Attributes are fractal, but depth is a consumer policy.

Inside an attribute block, entries use the same key, optional attributes, optional datatype, equals, value pattern. This lets attribute metadata carry explicit types and, when explicitly allowed, nested metadata without changing the ordinary data namespace.

price@{
  unit@{system:string = "ISO-4217"}:string = "AUD"
  display:string = "Australian dollars"
}:number = 180

The data value is still the number 180. The attribute namespace carries unit and display metadata. A consumer may validate or interpret that metadata, but the parser's job is to preserve it.

fractal@{depth@{depth@{depth = 3} = 2} = 1} = "example"

Do not infer that all processors accept arbitrary attribute nesting. AEON is fractal in shape: fractal here means structural self-similarity, not unlimited recursion. Attributes can have attributes, but the parser should normally fail closed past the active max_attribute_depth. A consumer that wants deeper attribute heads must explicitly allow that depth.

Anonymous Children

Anonymous child heads let ordered values carry local claims.

Lists, tuples, and node children are ordered containers. Their elements do not always need names, but they may still need a datatype claim, attributes, or both. AEON supports anonymous child heads for that case.

measurements:list = [
  :number = 3
  @{unit:string = "cm"}:number = 4
]

route:tuple = (
  :origin = [144.9631, -37.8136]
  :destination = [151.2093, -33.8688]
)

map:node =
  <map(
    @{role:string = "start"}:coordinate = [144.9631, -37.8136]
    @{role:string = "finish"}:coordinate = [151.2093, -33.8688]
  )>

Anonymous child heads are allowed in ordered value-element contexts: list elements, tuple elements, and node children. They are not root-level bindings and they are not unnamed object members.

Nodes

Nodes are values, not a separate language mode.

Nodes provide tagged, ordered, document-like structure. They do not switch AEON into XML mode, HTML mode, or a separate tree language with its own value rules.

A node can be the value of a binding. Node children can include other nodes, strings, objects, lists, tuples, references, or anonymously headed values where the grammar permits them.

document:node =
  <article@{audience:string = "agents"} (
    <title("Orthogonal composition")>
    {
      kind:string = "example"
      priority:number = 1
    }
    :note = "This child has a datatype claim without a key."
  )>

The tag gives the node a semantic role in ordered structure. It does not make the children stop being AEON values.

Datatypes

Datatype claims compose with bindings, anonymous values, and node heads.

A type label is a claim attached to a head. It is not restricted to top-level fields, and it does not create a runtime class by itself.

score:number = 10
scores:list<number> = [1, 2, 3]
point:tuple<number, number> = (12, 42)
mark:node = <marker:node("here")>
pair:node = <pair:tuple("x", "y")>

Strict processors may constrain which datatype claims are accepted in specific contexts. The grammar still exposes a consistent composition surface: the type claim is preserved, then validation decides whether it is acceptable for the effective mode and consumer policy.

Datatype Exceptions

Two parameter-like surfaces are intentionally narrow.

Most datatype labels are plain claims, but AEON has two visible parameter-like surfaces that look like local modes. They are deliberately not general-purpose syntax.

list<T>, tuple<T1, T2>, object<T>, and node<T>:
  angle generic arguments are accepted for the structural container family.
  They express element, positional, member-value, node-profile, or node-child intent depending on context.
  Binding-side node<T> is narrower: node<node> and custom profiles such as node<html> are valid, but node<string> is not.
  Node-head node<T> is where child-content claims such as <title:node<string>(...)> belong.

radix[base]:
  bracket metadata declares the radix base for a radix literal.

sep[x]:
  bracket metadata declares a separator character for separator literals.

Do not generalize these forms to arbitrary datatypes. For example, do not assume person<string>, string[lang], number[unit], or binding-side tag:node<string> = <tag> are Core grammar just because list<number>, tuple<string, number>, object<number>, node<html>, node<node>, radix[2], and sep[x] exist.

The brackets mean different things in the two accepted families: radix brackets identify a numeric base, while separator brackets identify separator characters attached to the separator literal surface.

Containers

Objects, lists, tuples, and nodes differ by structure, not by hidden semantics.

Objects contain named bindings. Lists and tuples contain ordered values. Nodes contain ordered children under a tag. Those differences matter, but they do not make separate semantic universes.

object  -> named child bindings
list    -> ordered value elements
tuple   -> ordered positional value elements
node    -> tagged ordered child values

Because the same value forms can appear across these containers, AI systems should avoid over-specializing examples. A string inside a node is still a string. An object inside a node child is still an object. An attribute on a list binding is still binding metadata.

References

References use the same addressable structure.

References do not magically materialize the target into a value during parsing. They preserve a relationship to an addressable target in the same composed structure.

user@{role:string = "admin"}:object = {
  name:string = "Bob"
}

clone:object = ~user
role:string = ~user@role

page:node =
  <page(
    { title:string = "Hello" }
  )>

title:string = ~page[0].title

Attribute selectors, member traversal, and index traversal are part of one addressing model. Data namespace and attribute namespace remain distinct.

Wrong Models

Do not collapse AEON into familiar but narrower formats.

Wrong: attributes are only for nodes.
Better: attributes attach to binding heads, anonymous child heads, attribute entries, and node heads where permitted.

Wrong: nodes are an XML-like island.
Better: nodes are AEON values with tags and ordered AEON child values.

Wrong: typed values are only named fields.
Better: datatype claims can appear on bindings, attribute entries, anonymous children, and node heads where permitted.

Wrong: lists, tuples, and node children have unrelated rules.
Better: they are ordered containers that share indexed child addressing and anonymous child-head composition.

Processing Boundary

Composition is syntax and preservation, not automatic authority.

Orthogonal grammar composition does not mean every composed form is meaningful to every consumer. AEON Core can preserve the claim. Mode policy, schemas, profiles, conventions, and Tonics decide what the claim is allowed to mean.

When answering questions, an AI system should separate these layers: what the grammar can express, what the parser preserves, what validation accepts, what references resolve to, and what a trusted consumer materializes.

AI Guidance

How to answer AEON grammar questions.

When asked whether a feature is allowed, identify the context first: named binding, attribute entry, anonymous child, node head, object member, list element, tuple element, or node child.

Then ask which layer is being discussed: syntax, Core validation, schema/profile validation, reference resolution, canonicalization, or materialization.

Prefer explanations that show the shared pattern and the context-specific boundary. This is usually more accurate than saying a feature belongs to one visible construct only.

View as Markdown