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

Dejan Lekic dejan.lekic at gmail.com
Thu Sep 24 12:40:30 UTC 2026


On Thursday, 24 September 2026 at 00:21:53 UTC, Meta wrote:
> 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);
> ```

Is it me or this is just terrible, and this is just a tiny 
example. For anything more serious (read - real world use cases) 
the amount of ugly code like the one above would be enormous...


More information about the dip.development mailing list