Skip to content

Specification

This is the normative half of the docs. Where the Guide is a narrative tour, the Specification is the reference you reach for when you need the exact rule — the keyword table, the resolution precedence, the IL a construct lowers to, the diagnostic a mistake triggers. Terse and tabular by design; the prose lives in the Guide.

The IL compiler is the language. E# has two backends over one typed IR — the IL compiler (.es → Mono.Cecil → .dll) and a secondary transpiler (.es → C# → Roslyn). The IL compiler owns the semantics; when the two disagree, the IL compiler is correct and the transpiler is the bug. Every claim here is demonstrable. The corpus is drawn from the language’s own test suite and samples — passing test cases, showcases, and integration tests (some sizeable, multi-file) — and each entry earns its place: it compiles cleanly (or, for the negative cases, is rejected with exactly its expected diagnostic) and either produces its asserted output or stands as a real, well-formed program. The Diagnostics catalog deep-links each error code to the negative examples that provoke it, so the corpus is browsable by diagnostic.

E# uses initial case to carry the value/type distinction, which keeps the grammar unambiguous (a bare uppercase name is always a type, so Foo { ... } always reads as construction).

KindCasingEnforced by
Types — data, ref data, choice, ref choice, enum, interface, static func, delegate funcPascalCaseES2160 (hard error)
Free functionscamelCaseES2161 (hard error)
Methods (first param is a data receiver) and static func membersPascalCase allowed (to match .NET)
constSCREAMING_SNAKE_CASEconvention only

Grammar is given in EBNF, in the style of the Go specification:

Production = production_name "=" [ Expression ] "." .
Expression = Term { "|" Term } .
Term = Factor { Factor } .
Factor = production_name | token | "(" Expression ")" | "[" Expression "]" | "{" Expression "}" .

[ x ] is optional, { x } is zero-or-more repetition, ( x ) groups, a | b alternates, "x" is a literal token, and a … b is a character range. Lower-case names are lexical (token) productions; upper-case names are syntactic. “It is an error if …” and “shall” introduce normative static-semantic rules, each cross-referenced to the diagnostic it raises.

A conforming program is one the IL compiler accepts and whose emitted assembly passes ILVerify. A program that violates a static-semantic rule is ill-formed; the compiler shall reject it with the named diagnostic. Behaviour the compiler accepts but this document does not describe is unspecified.

PageCovers
Lexical structureencoding, comments, identifiers, keyword tables, operators, literals, string interpolation
Names & resolutionnamespaces, using forms, the 3-tier resolution precedence, ambiguity, per-file scope
CLR mappingthe full E# → C# → IL lowering table
Diagnosticsevery ES#### code — trigger, fix, and the corpus examples that demonstrate it

More pages (types, inheritance, allocation & representation, functions, pointers & by-ref, expressions & statements, errors, concurrency, delegates & events, interop, limitations) extend the same normative treatment to the rest of the language.

E# is pre-alpha: no LSP, no operator overloading, type inference only in trivial cases, a young .esproj build. The language is real and tested, but the surface still moves. Where a feature is absent or a C# convenience is missing, the relevant page says so plainly rather than dressing the gap as a design statement — see Limitations & roadmap.