Skip to content

introduce vertical void attributes (? > name) and atom error-formas (/{…}) (part of #5261) #5267

Description

@maxonfjvipon

Part of the fragile-objects epic #5261. This ticket covers the two ? -headed body-line forms the epic introduces: plain vertical void attributes (any formation) and atom error-formas (/{…}, atoms only).

1. Vertical void attributes — ? > name

The epic makes the two snippets equivalent:

[name] > foo        |   [name bar test] > foo
  ? > bar           |
  ? > test          |

A ? > name body line declares a void attribute on the enclosing formation. The ? glyph is currently free — it was a NAME terminator only, and its legacy atom-return-type use was dropped from the grammar in #5078 — so this repurposes it.

XMIR contract

A vertical void emits exactly the element a bracket param does (§9.4):

<o name="bar" base=""/>

It is therefore indistinguishable in XMIR from [… bar …]. Consequences:

  • move-voids-up.xsl already hoists every child to the front, so a body-declared void lands among the head voids with no XSL change. The equivalence [name] + ? > bar + ? > test ≡ [name bar test] falls out of that pass.
  • No runtime or transpiler work voids are handled end to end already.
  • Reverse printing canonicalizes to the bracket form; the printer cannot recover which form was written, and the two are equivalent by definition. Round-trip tests expect the bracket form.

Surface syntax

  • A ?-headed body line with a mandatory > name suffix: ? > bar.
  • Legal only as a direct child of a formation. A ? line elsewhere, or a ? without a > name, is a parse error.
  • ? > @ is allowed (a void named φ), mirroring R-3.4.2 which admits @ as a bracket void param.

2. Atom error-formas — ? > name /{forma …}

In an atom, a vertical void may carry a brace-delimited forma-list:

[name] > fopen /file
  ? > not-found /{string io.file-error}
  ? > cant-open /{io.foo.bar.super-error}

Here /{string io.file-error} are the formas the fopen atom provides as the arguments for not-found when it triggers that branch. Grammar: /{ forma (SPACE forma)* }, where each forma is a dotted name (NAME ('.' NAME)*, optionally Q-rooted) — the same shape as an atom /sig.

Atoms only

The /{…} suffix is legal only on a vertical void whose enclosing formation is an atom (its head carries /sig). A /{…} in a non-atom formation is a parse error. This restriction must be stated in the spec.

XMIR contract — the @types attribute

The forma-list maps to a new multi-valued @types attribute on the void — not child objects. Each space-separated forma is resolved exactly the way @atom is (alias expansion + default-package prefixing, with QΦ per §9.3), so the parsed XMIR holds fully-qualified, Φ-rooted names:

<o name="not-found" base="" types="Φ.string Φ.io.file-error"/>
  • The parser first emits the raw, space-separated formas (e.g. types="string io.file-error"); the existing FQN passes then resolve each token.
  • Because @types is multi-valued (unlike single-valued @atom), resolve-aliases.xsl and add-default-package.xsl must split @types, resolve each token the same way they resolve @atom, and rejoin. Aliases (+alias) are honoured per token, exactly as for @atom.
  • The void keeps @base='∅', so eo:void detection and move-voids-up are unaffected.

Implementation sketch (spec-driven parser)

  • PARSER_SPEC.md — add ? (VOID) to §2.3; a vertical-void clause and the /{…} forma-list grammar to §3.x; the atoms-only restriction; and the §9.x emission for both forms (the void and the @types attribute, noting @types resolves like @atom).
  • Recognize a ?-headed line in Eo.classify; parse ? > name and the optional /{…} suffix; emit the void child, plus the raw @types attribute when a forma-list is present.
  • Extend resolve-aliases.xsl and add-default-package.xsl to resolve each space-separated token of @types like an @atom.
  • Close-time validation: ? outside a formation, ? without a name, and /{…} outside an atom are all reported.
  • Verify the rest of the parse pipeline leaves the new emission intact (move-voids-up, mandatory-as, build-fqns).

Tests

  • Parse pack: [name] > foo + ? > bar + ? > test[name bar test] > foo (same three voids, in order), surviving the full pipeline.
  • Parse pack: atom fopen with ? > not-found /{string io.file-error} emits the void with @types="Φ.string Φ.io.file-error" (FQN-resolved); a variant with an +alias confirms per-token alias resolution.
  • Parse pack / negative: /{…} in a non-atom formation is rejected.
  • EoTest: ? > x emits <o name='x' base='∅'/>.
  • Round-trip test documenting that vertical voids print back as bracket params.

Out of scope

The ?. operator, fragile-object detection, and runtime semantics — separate #5261 sub-tickets.

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions