First Draft: Nominal Sum Types via `enum union` and `switch` Expressions

Nick Treleaven nick at geany.org
Fri Sep 25 10:37:12 UTC 2026


On Wednesday, 23 September 2026 at 22:15:09 UTC, Meta wrote:
> On Wednesday, 23 September 2026 at 09:14:43 UTC, Dukc wrote:
>> Doesn't that feel limiting? Consider matching a primitive 
>> type. Do you feel this should not be allowed?
>>
>> ```d
>> import std.conv;
>>
>> auto var = case(aString.front)
>> {
>>     case '\r' => fun(),
>>     case '\n' => gun(),
>>     // Unicode replacement character
>>     case to!dchar(0xFFFD) => hun(),
>> };
>> ```
>
> No, it shouldn't be allowed.
>
>> Remember, existing `switch` statements allow this. Why 
>> `switch` expressions wouldn't?
>
> Because switch statements match against values, while switch 
> expressions match against patterns. Patterns only exist at 
> compile time, so a function call cannot be a pattern.

`to!dchar(0xFFFD)` is evaluable with CTFE, and I think it could 
be allowed as a constant pattern. I don't see why the function 
call/type constructor pattern ambiguity is necessarily a problem, 
we already have that ambiguity as an expression. I suppose it is 
because `Type(ident)` would declare `ident` as a symbol if 
`ident` doesn't exist in the scope, and whether something is a 
declaration should not depend on whether an identifier is in 
scope. If we used `Type(auto ident)` it would be more verbose but 
more consistent, e.g. with tuple unpacking declarations: `(auto 
first,) = tuple(1)`.

Also, banning a CTFE function call as a pattern itself would 
still leave `Type(someManifestConstant)` syntax, which again we 
may want to support.

...
> That being said, you're right that this would be tedious to do 
> with the proposal as it is now.
>
> For this specific DynamicNumber case, this *should* work 
> (should as in it doesn't right now because static foreach isn't 
> allowed in a switch expression, but should be made to work):
> ```d
> ...
>     return switch (a)
>     {
>         // Already handled the error case above, but this is 
> needed to satisfy the exhaustiveness check
>         default => assert(0),
>         static foreach (V1; NumericVariants)

That would be an inconsistency in the language, static foreach is 
a declaration or a statement, and we don't allow declarations in 
an expression. People would ask why they can't use static foreach 
in other expressions. If we had pattern matching for a switch 
statement then static foreach would work naturally.


More information about the dip.development mailing list