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

Meta jared771 at gmail.com
Thu Sep 24 00:21:53 UTC 2026


On Wednesday, 23 September 2026 at 22:23:46 UTC, Meta wrote:
> That can be simplified to:
> ```d
> enum union DynamicNumber
> {
>     case long, float, double, error(string);
> }
>
> DynamicNumber sum(DynamicNumber a, DynamicNumber b) @safe
> {
>     enum isBare(alias V) = __traits(variantKind, V) == "bare";
>     alias NumericVariants = Filter!(isBare, 
> __traits(allVariants, DynamicNumber));
>     return switch (a)
>     {
>         case error => a,
>         static foreach (V1; NumericVariants)
>             case V1 v1 => switch (b)
>             {
>                 case error => b,
>                 static foreach (V2; NumericVariants)
>                     case V2 v2 => DynamicNumber(v1 + v2),
>             },
>     };
> }
> ```
>
> Actually that's pretty straightforward for a fairly complex 
> case. The only thing that's needed is static foreach support 
> for generating switch arms, which is on my todo list already.

And it's now implemented:
```d
enum union Shape
{
     case Circle(double);
     case Rect(double, double);
     case Point();
}

double area(Shape s)
{
     return switch (s)
     {
         static foreach (T; __traits(allVariants, Shape))
         {
             static if (__traits(identifier, T) == "Circle")
             {
                 case Circle(r) => 3.14159 * r * r,
             }
             else static if (__traits(identifier, T) == "Rect")
             {
                 case Rect(w, h) => w * h,
             }
             else
             {
                 // Optional trailing delimiter before right curly
                 case Point() => 0.0
             }
         }
     };
}

Shape sh = Shape.Rect(3.0, 4.0);
assert(area(sh) == 12.0);
```


More information about the dip.development mailing list