Skip to content

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.

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.

Grammar is shown in ANTLR-style EBNF in ebnf code blocks:

value_declaration
: 'value' identifier '{' member* invariant* '}'
;

The conventions:

NotationMeaning
'value'a literal terminal (keyword, operator, or punctuation)
UpperCamela lexical token (produced by the lexer — e.g. Identifier, IntLiteral)
lower_snakea syntactic rule (produced by the parser)
x?zero or one x
x*zero or more x
x+one or more x
a | beither 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.

This specification uses themed asides:

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.

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