From cfedfe4e0f202a4705649c700aba5ef3bfd4f24a Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Wed, 24 Sep 2025 19:00:38 -0700 Subject: [PATCH 1/4] Expanded enums and unions This document introduces the concepts of enums and unions, detailing their syntax, semantics, and expansion options. It provides examples and grammar definitions for both types. --- .../discriminated-unions/enums-and-unions.md | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 meetings/working-groups/discriminated-unions/enums-and-unions.md diff --git a/meetings/working-groups/discriminated-unions/enums-and-unions.md b/meetings/working-groups/discriminated-unions/enums-and-unions.md new file mode 100644 index 0000000000..5f8cab30fc --- /dev/null +++ b/meetings/working-groups/discriminated-unions/enums-and-unions.md @@ -0,0 +1,131 @@ +# Enums and unions + +## Abstract + +This proposal separates two high-level concepts into two separate syntaxes: `enum` and `union`. Unions are a type declaration that represent the union of existing types. Enums are a compositional type syntax. They allow declaring a sequence of nested types, each of which are unioned into the parent type. This is also known as an "algebraic data type". Union declarations take a list of existing types as input, while the enhanced enum syntax takes a list of type names, parameter lists, and bodies. + +## Example + +Union declaration: + +```C# +union StringOrInt +{ + string, + int +} +``` + +Enum declaration: + +```C# +enum JsonValue +{ + Number(double value), + Bool(bool Value), + String(string Value), + Object(ImmutableDictionary Members), + Array(ImmutableArray Elements), + Null +} +``` + +## Syntax + +Expanded enum: +```bnf + ::= "enum" "{" "}" + ::= { "," } [ "," ] + ::= [ "(" ")" ] + ::= { "," } + ::= + ::= | + ::= "double" | "bool" | "string" | + ::= "<" ">" + ::= { "," } + ::= identifier + ::= identifier + ::= identifier +``` + +Union: +```bnf + ::= "union" "{" "}" + ::= { "," } [ "," ] + ::= | + ::= "double" | "bool" | "string" | "int" | + ::= "<" ">" + ::= { "," } + ::= identifier +``` + +## Semantics + +An enum has the same semantics as declaring all the cases as nested records, then making a union e.g., + +```C# +union JsonValue +{ + Number, + Bool, + String, + Object, + Array, + Null; + + record Number(double value); + record Bool(bool Value); + record String(string Value); + record Object(ImmutableDictionary Members); + record Array(ImmutableArray Elements); + record Null; +} +``` + +## Expansion options + +The above grammar doesn't provide more than the minimal set of syntax. There are a few small additions that could be easily made. + +### Allow extra members after a semicolon + +In both enums and unions, after a semicolon additional members could be provided. Fields. auto-properties, and any other syntax that create additional fields would be prohibited. + +## Allow extra members in a partial declaration + +All enums and unions would have a so-called "primary" declaration that lists the union/enum members. Other partial declarations could be allowed, which would allow extra members. Again, no fields would be allowed. + +## Allow record bodies in enums + +Enums could be expanded to allow each declaration to have a body, e.g. + +```C# +enum JsonValue +{ + Number(double Value) + { + public override string ToString() => Value.ToString(); + }, + Bool(bool Value) + { + public override string ToString() => Value.ToString(); + }, + String(string Value) + { + public override string ToString() => Value.ToString(); + }, + Object(ImmutableDictionary Members) + { + public override string ToString() => Value.ToString(); + }, + Array(ImmutableArray Elements) + { + public override string ToString() => Value.ToString(); + }, + Null + { + public override string ToString() => "null"; + } +} +``` + +If partial declarations of enums are allowed, the type members could also themselves be partial. From adf1d8662615816162ccbfc788a5c35950c270f2 Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Wed, 24 Sep 2025 19:02:01 -0700 Subject: [PATCH 2/4] Update section headers for enums and unions --- .../working-groups/discriminated-unions/enums-and-unions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meetings/working-groups/discriminated-unions/enums-and-unions.md b/meetings/working-groups/discriminated-unions/enums-and-unions.md index 5f8cab30fc..cdb91f0057 100644 --- a/meetings/working-groups/discriminated-unions/enums-and-unions.md +++ b/meetings/working-groups/discriminated-unions/enums-and-unions.md @@ -90,11 +90,11 @@ The above grammar doesn't provide more than the minimal set of syntax. There are In both enums and unions, after a semicolon additional members could be provided. Fields. auto-properties, and any other syntax that create additional fields would be prohibited. -## Allow extra members in a partial declaration +### Allow extra members in a partial declaration All enums and unions would have a so-called "primary" declaration that lists the union/enum members. Other partial declarations could be allowed, which would allow extra members. Again, no fields would be allowed. -## Allow record bodies in enums +### Allow record bodies in enums Enums could be expanded to allow each declaration to have a body, e.g. From 77de8ffe21a01e4202c0991e755fbb58c3cfdbdc Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Wed, 24 Sep 2025 20:18:50 -0700 Subject: [PATCH 3/4] Update meetings/working-groups/discriminated-unions/enums-and-unions.md Co-authored-by: Joseph Musser --- .../working-groups/discriminated-unions/enums-and-unions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meetings/working-groups/discriminated-unions/enums-and-unions.md b/meetings/working-groups/discriminated-unions/enums-and-unions.md index cdb91f0057..a973663c45 100644 --- a/meetings/working-groups/discriminated-unions/enums-and-unions.md +++ b/meetings/working-groups/discriminated-unions/enums-and-unions.md @@ -88,7 +88,7 @@ The above grammar doesn't provide more than the minimal set of syntax. There are ### Allow extra members after a semicolon -In both enums and unions, after a semicolon additional members could be provided. Fields. auto-properties, and any other syntax that create additional fields would be prohibited. +In both enums and unions, after a semicolon additional members could be provided. Fields, auto-properties, and any other syntax that create additional fields would be prohibited. ### Allow extra members in a partial declaration From b8256f52cfacae6eee6c1d6a95d40a218f4b72f0 Mon Sep 17 00:00:00 2001 From: Andy Gocke Date: Mon, 6 Oct 2025 15:22:35 -0700 Subject: [PATCH 4/4] Update ToString method for Object and Array cases --- .../working-groups/discriminated-unions/enums-and-unions.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meetings/working-groups/discriminated-unions/enums-and-unions.md b/meetings/working-groups/discriminated-unions/enums-and-unions.md index a973663c45..3312260614 100644 --- a/meetings/working-groups/discriminated-unions/enums-and-unions.md +++ b/meetings/working-groups/discriminated-unions/enums-and-unions.md @@ -115,11 +115,11 @@ enum JsonValue }, Object(ImmutableDictionary Members) { - public override string ToString() => Value.ToString(); + public override string ToString() => Members.ToString(); }, Array(ImmutableArray Elements) { - public override string ToString() => Value.ToString(); + public override string ToString() => Elements.ToString(); }, Null {