<!-- 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.

```aeon
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.

```aeon
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.

```aeon
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.

```aeon
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.

```aeon
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.

```aeon
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.

```aeon
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.

```aeon
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.

## Definitions

¹ **Claim:** something the document says about structure, type, intent, relationship, or meaning. Claims are preserved by AEON and accepted, rejected, or interpreted by consumers.

² **Value:** the assigned content of a binding or anonymous item: a scalar, object, list, tuple, node, reference, prose block, encoded value, or special literal.

³ **Node:** a tagged tree value for ordered, nested, document-like structure. Nodes are semantic structures that may later materialize as HTML, Markdown, PDFs, UI trees, or other projections.

⁴ **Type label:** an explicit claim about the intended value family or domain type. A type label is preserved by the parser; it is not automatically a runtime class.

⁵ **AEON Core:** the core language and parser layer responsible for recognizing AEON syntax and preserving structure as assignment events, without deciding domain meaning.

⁶ **Tonic:** a trusted materializer or consumer-side adapter that turns accepted AEON meaning into a runtime object, rendered document, API payload, or other projection.
View as HTML