Design decisions (ADRs)
This is a curated reference index of the Architecture Decision Records in the repository. ADRs explain design intent and tradeoffs; they are not the normative language specification. Each link points to the source ADR on GitHub.
Null model, values, and primitives
| ADR | Title | Summary |
|---|---|---|
| 0001 | Absence / null model — Kotlin-style nullable types | Uses explicit nullable T?, nil, safe access, and assertion instead of a universal null. |
| 0008 | Variable bindings — keep Go's var/const/:=, add let | Keeps familiar Go declarations while adding immutable let. |
| 0015 | Multi-target assignment evaluation order | Evaluates all right-hand values before observable writes, matching Go swap semantics. |
| 0016 | Slice backing storage — T[] | Represents slices with CLR single-dimensional zero-based arrays. |
| 0044 | Complete numeric primitive coverage | Defines full width-bearing numeric primitive coverage and conversion behavior. |
| 0045 | object as the universal upper bound | Makes object the top type for assignment compatibility, boxing, and object equality. |
| 0046 | 'c' character literal grammar | Specifies character literal grammar, escapes, static type, and diagnostics. |
| 0049 | Width-bearing integer keyword names | Chooses explicit names such as int32 and uint64 over ambiguous aliases. |
Concurrency, async, and resource scope
| ADR | Title | Summary |
|---|---|---|
| 0002 | Concurrency model — Go surface, .NET runtime, Kotlin scopes | Combines Go-like go/channel syntax with .NET tasks and structured scopes. |
| 0022 | go / chan / select → .NET lowering | Defines how goroutine-like calls, channels, send/receive, and select lower to .NET. |
| 0023 | async func / await — state-machine strategy | Commits to compiler-generated async state machines for emitted async functions. |
| 0030 | defer and block-scoped cleanup convergence | Makes cleanup block-scoped and aligns defer with using/finally lowering. |
| 0040 | sequence[T] type alias and yield statement | Introduces sequence types and iterator yield statements. |
| 0041 | sequence[T] in an async context aliases IAsyncEnumerable[T] | Explores async sequence feasibility and binding shape. |
| 0042 | async sequence[T] as a type-clause spelling for IAsyncEnumerable[T] | Chooses an explicit type-clause spelling for async streams. |
| 0043 | async func(P) R as a type-clause spelling for func(P) Task[R] | Defines async function type clauses as task-returning function types. |
Object model, OO, and data types
| ADR | Title | Summary |
|---|---|---|
| 0003 | OO surface — data-oriented core with light OO escape hatch | Adds classes/interfaces without making OO the center of the language. |
| 0017 | Method virtuality — sealed by default, opt-in with open | Requires explicit open for inheritable classes and overridable methods. |
| 0018 | Interface default methods — not in Phase 3 | Defers default interface methods from the early interface surface. |
| 0024 | Methods with receivers vs. extension functions canonical style | Establishes receiver functions as the canonical extension/method style. |
| 0025 | record keyword alias for data struct | Makes record syntactic sugar for data struct. |
| 0029 | data struct synthesized members | Defines synthesized equality, copy, and ergonomic members for data structs. |
| 0032 | Data-struct ergonomics polish | Refines copying, deconstruction, and update syntax for data structs. |
| 0033 | Inline value classes / inline struct | Introduces single-field inline structs for value-class ergonomics. |
| 0051 | Property declarations — prop keyword with accessor bodies | Specifies property syntax, auto-properties, and accessors. |
| 0052 | Event declarations on user types — event keyword | Defines field-like and custom event declarations on user types. |
| 0053 | Static members on user types — shared block | Adds static fields, methods, properties, and events through a shared block. |
Generics and functions
| ADR | Title | Summary |
|---|---|---|
| 0004 | Generics — consumption and definition in a single phase, with constraints | Defines initial generic types/functions, constraints, and type-erased implementation tradeoffs. |
| 0020 | Generic type-parameter brackets — Go-style [T] | Chooses square brackets for type parameters and type arguments. |
| 0021 | Generic variance modifiers — in / out on interface type parameters | Adds variance markers for interface type parameters. |
| 0038 | Type-argument inference for imported open generic methods | Defines inference for imported generic method calls and associated emit fixes. |
| 0050 | -> arrow trailing-lambda syntax | Proposed shorthand for trailing lambdas; not part of the current implemented grammar. |
Error handling and control flow
| ADR | Title | Summary |
|---|---|---|
| 0005 | Error handling — exceptions only, unchecked | Uses CLR exceptions instead of checked exceptions or Go-style error returns. |
| 0009 | switch semantics — expression + statement, patterns, exhaustive | Defines switch statements, switch expressions, patterns, and exhaustiveness. |
| 0013 | Drop Go's fallthrough | Reserves fallthrough but rejects it; cases never fall through. |
| 0031 | Canonical for x in collection | Establishes for x in collection as the preferred range iteration spelling. |
Syntax, naming, and documentation policy
| ADR | Title | Summary |
|---|---|---|
| 0006 | Visibility — explicit modifiers, public default | Replaces Go capitalization export rules with explicit visibility modifiers. |
| 0007 | String interpolation syntax — Kotlin-style | Chooses $name and ${expr} interpolation forms. |
| 0010 | Aspirational samples policy — rewrite to today's subset, re-expand per phase | Keeps samples aligned with implemented language phases. |
| 0011 | String interpolation grammar and lowering | Specifies interpolation parsing and lowering details. |
| 0012 | Raw string delimiter — backtick | Chooses backtick-delimited raw strings. |
| 0014 | Visibility defaults — public for top-level declarations | Makes unmodified top-level declarations public by default. |
| 0054 | Postfix member/index access on primary expressions | Chains ./?./[] after any primary except a bare numeric literal ((42).Member). |
| 0055 | String interpolation revamp | Delimiter-aware multiline holes, alignment/format clauses, late context-driven lowering (DefaultInterpolatedStringHandler/FormattableString), and full IDE support inside holes. |
| 0057 | Documentation comments | Markdown-authored /// documentation comments with lossless CLR XML-doc round-trip; hover renders the merged XML on imported APIs. Diagnostics GS0227–GS0231. |
| 0062 | Generalized ternary expression | Promotes cond ? a : b from the narrow ADR-0061 ref form to a normal expression; retires GS0259 in value contexts and adds GS0263. |
CLR interop
| ADR | Title | Summary |
|---|---|---|
| 0019 | Extension function declaration syntax — func (Receiver) Name(...) ... | Defines receiver-based extension function syntax. |
| 0026 | Operator-by-name on user types — deferred | Defers user operator naming until a later design is chosen. |
| 0034 | Imported CLR interop — static members, writes, operators, conversions, overload resolution | Extends imported CLR support across static members, writes, operators, conversions, and overloads. |
| 0035 | User-defined operator keyword on GSharp types | Adds receiver-style operator declarations for G# types. |
| 0036 | CLR event subscription with += / -= | Uses assignment-like syntax for CLR event add/remove. |
| 0037 | Numeric better-conversion target tie-breaking in overload resolution | Defines numeric conversion ranking for overload resolution. |
| 0039 | By-ref pointers and CLR interop for ref / out / in parameters | Introduces *T, &, dereference, ref arguments, and related diagnostics. |
| 0047 | Attribute consumption and declaration (Kotlin-style annotations) | Defines @ annotation syntax, use-site targets, attribute arguments, and @Attribute sugar. |
| 0056 | Span consumption v1 — ref-returning members, span element access, closed generic value-type fields | Auto-dereferences ref-returning members in rvalue position, makes spans indexable (read/write), applies []T → Span[T] conversion in argument position, and gives closed generic value-type fields real layout. |
| 0058 | Ref-safe-to-escape and the scoped modifier | Adds the scoped parameter modifier and the supporting GS9004/GS9006 ref-pointer escape diagnostics. |
| 0059 | Named delegate types | type Name = delegate func(...) declares a real CLR MulticastDelegate-derived type; diagnostics GS0233–GS0234. |
| 0060 | ref/out/in parameters | Declaration-site and call-site ref-kind modifiers with diagnostics GS0235–GS0243; ref-aliasing locals (let ref/var ref) and ref returns are follow-ups (GS0248–GS0258). |
| 0061 | Conditional ref-arguments | Narrow ref cond ? a : b form inside ref-kind argument payloads; diagnostics GS0259–GS0262. |
| 0063 | Method overloading and optional parameters | Lifts the v0 "one declaration per name" rule and adds default parameter values; diagnostics GS0264–GS0267. |
Emit and tooling
| ADR | Title | Summary |
|---|---|---|
| 0027 | Roslyn-fork decision for v1.0 — stay on the bespoke emitter | Keeps the direct metadata emitter instead of adopting a Roslyn fork for v1.0. |
| 0028 | Multi-package emit model — Option B, C#-faithful | Defines how multiple packages map to emitted CLR namespaces/types. |
| 0048 | Portable PDB emit | Adds portable PDB, source mapping, and debug-symbol policy to the emitter. |