Notation & conventions
This page explains the conventions used throughout the Koine language specification. It is the reference for how to read the chapters that follow — the structure of each page, the grammar notation, how sections are numbered and cross-referenced, and what the callouts mean.
2.1 How this specification is organized
Section titled “2.1 How this specification is organized”Each construct chapter (a value object, an entity, the expression language, …) follows the same spine, so you can predict where any fact lives:
- General — what the construct is and the domain-modelling role it plays.
- Syntax — the grammar of the construct, as one or more EBNF productions, followed by prose describing each part.
- Semantics — the rules: well-formedness, defaults, derived members, validation, equality, and the diagnostics the compiler raises for ill-formed input.
- Translation to C# — the C# the current emitter produces for the construct.
Some chapters adapt this spine to their material — the expression language (§9), for example, is organized per operator rather than as a single Translation section.
This deliberately separates what you write (Syntax) from what it means (Semantics) and what it becomes (Translation). Koine’s semantic model is target-agnostic and drives several emitters — C#, TypeScript, Python, PHP, and Rust today (Rust covers multi-context models and the CQRS read side) — so every “Translation” section in this reference describes the C# emission specifically, not the language itself.
2.2 Grammar notation
Section titled “2.2 Grammar notation”Grammar is shown in ANTLR-style EBNF in ebnf code blocks:
value_declaration : 'value' identifier '{' member* invariant* '}' ;The conventions:
| Notation | Meaning |
|---|---|
'value' | a literal terminal (keyword, operator, or punctuation) |
UpperCamel | a lexical token (produced by the lexer — e.g. Identifier, IntLiteral) |
lower_snake | a syntactic rule (produced by the parser) |
x? | zero or one x |
x* | zero or more x |
x+ | one or more x |
a | b | either a or b |
( … ) | grouping |
The grammar shown here is hand-curated for readability. The canonical, build-time grammar is the
ANTLR source in
KoineLexer.g4
and
KoineParser.g4;
where this specification simplifies a production for clarity, those files win.
One simplification is pervasive: member, parameter, and type-name positions are written as Identifier,
but in the grammar these positions also accept soft keywords (§3.5.2) —
so a field, parameter, or read-model column may legitimately be named version, from, or any other soft keyword.
2.3 Section numbering and cross-references
Section titled “2.3 Section numbering and cross-references”Every chapter owns a fixed chapter number (shown in the sidebar as 5 · Value objects). Section
headings within a chapter carry that number as a prefix — ## 5.1 General, ### 5.2.1 Fields — and
cross-references cite it with the § glyph, linking to the heading anchor:
See §5.2 for the value-object grammar.
Chapter numbers are stable: a new chapter added later takes the next free number; existing chapters are never renumbered, so anchors and inbound links stay valid.
2.4 Notes, examples, and callouts
Section titled “2.4 Notes, examples, and callouts”This specification uses themed asides:
2.5 Diagnostics
Section titled “2.5 Diagnostics”When the compiler rejects ill-formed input it raises a diagnostic with a stable code of the form
KOI#### and a symbolic name. Semantics sections cite these inline, e.g. “declaring a type named
List raises KOI0908 (ReservedTypeName)”. The codes are part of the compiler’s contract and are
safe to match on in tooling.
2.6 Emitted C#
Section titled “2.6 Emitted C#”“Translation to C#” sections show idiomatic C# from the current emitter (Emit/CSharp/). The emitted
code is snapshot- and compile-tested in the repository, so the shapes shown are real. Because the
language is target-agnostic, the same model drives other emitters too (TypeScript, Python, PHP, and
Rust ship today — Rust covers multi-context models and the CQRS read side); only the Translation sections are C#-specific.