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