meetings/2025/LDM-2025-09-24.md
Champion issue: https://github.com/dotnet/csharplang/issues/9662
Specification: https://github.com/dotnet/csharplang/blob/38fd5f33d285cb190268f98cea16223cc0a5b8bc/proposals/unions.md
Proposals:
Today we begin the syntax thunderdome for unions: while we don't expect to make every decision today (and spoiler alert, we did not), we need to make enough progress today and
in the next couple of meetings for the compiler team to start implementation without later needing to significantly redesign the parsing stages. We have a few different options
on the table, and we started to break them down by philosophies. Specifically, we have 2 main flavors of union here: a union that states that its cases are pre-existing
types, and a union that states that its cases are types that should be generated inline. One major question, therefore, is whether or not we expect these different flavors to
mix; do we expect users to often declare intermixed unions of both pre-existing types and new types, or do we expect it to be homogenous. And, if we often expect it to be
homogenous, do we really need a syntax that allows both flavors in a single union declaration? One key insight is that the union of newly created types is just sugar over the
union of pre-existing types; we can likely formalize the former as literally desugaring into the latter, with the new types declared as nested types within the union. This then
potentially allows us to nicely relate this back to enums; we can say that enums are for declaring new cases (whether that's numeric cases or types cases), and union is
specifically for bundling a group of existing types. We could then potentially allow a grow-up story for enums where they can add new types of members. Some difficult hurdles
remain in that area though:
enum is number-based or type-based? Is the difference just in whether any of the cases has nested values? Is that too subtle?
enum class or enum struct to convey this difference?System.Enum? Would we change the runtime to allow them to inherit from System.Enum? Would that be too large of a breaking change?
System.Enum, is that too large a divergence to continue using the enum keyword?We do think that this idea has some merit and needs to be explored, and several LDM members plan to do just that ahead of Monday's meeting. We also took some initial reads of
the room on the basic building blocks of unions. So far, LDM leans towards unions not having a dedicated shorthand syntax for declaring new types; they are made up of existing
types. We are not ruling out the separate enum of types idea that would desugar into a union with nested declarations, but to use an analogy to classes and records,
unions would be the more general building block on which a potential enum of types feature would build, just as classes are the building block on which records build.
We also thought about whether the cases of unions should be inside or outside the curly braces of the body. Again, there are no easy options here. If they are outside the
curly braces, our precedent for scoping visibility suggests that any nested types from inside the union are not visible without being qualified by the type of the union,
including any generic type arguments. However, in order to implement closed type hierarchies, we may need to have a list of the allowed implementations, similar to Java's
permits clause, both for compiler performance and for reader comprehension. If we do need to have such a clause for that case, it might be a good idea to unify that with
unions. On the other hand, unions could also reuse the enum syntax; again, if we expect to allow other member types to be defined in an enum, we will need to solve
the syntax question of both listing the cases and other members in the body of the enum, and union could potentially reuse that same syntax. Subjectively, we do have a
slight leaning that by writing the members inside the body, rather than at the declaration level, it implies that they are new things, rather than existing things. Given
that, we have a very slight lean towards outside the body of the union, but will explore more proposals on Monday and hopefully make further concrete progress on this very
gnarly question.