Second draft: Sum Type by Struct

Richard (Rikki) Andrew Cattermole richard at cattermole.co.nz
Tue Sep 8 20:19:13 UTC 2026


On 07/09/2026 10:04 PM, Nick Treleaven wrote:
> On Friday, 4 September 2026 at 08:20:42 UTC, Richard (Rikki) Andrew 
> Cattermole wrote:
>>> 7. "Catch-all arm: (x) => 42 — matches any variant, parameter type 
>>> inferred from variant"
>>>
>>> How does this work? In std.sumtype it works because the template 
>>> lambda acts as a catch all whose type is inferred, but I don't think 
>>> that can work outside of a template function context (?) Is the type 
>>> of x a synthesized union containing the types that weren't matched?
>>
>> The body gets copied for each arm that's needed, so it has a unique 
>> variant per instance.
> 
> So below, `other` has type bool?
> 
> ```d
> __sumtype Signed = int | bool;
> 
> // Guard with catch-all fallback
> int clampToHundred(Signed s)
> {
>      return s.match {
>          (int v) if (v > 100) => 100,
>          (int v) if (v < 0)   => 0,
>          (other)              => cast(int)other  // catch-all
>      };
> }
> ```
>  From https://gist.github.com/ 
> rikkimax/0ce50c459b1635a05c9de02fe44e2aee#examples.

Yes.

> It's notable that `cast(int)` is needed above, even though bool 
> implicitly converts to int. Presumably that's to stop the match result 
> type being `__sumtype(int | bool)` (which I discussed in [my other 
> reply](https://forum.dlang.org/post/cgurcqxggabfdvkbsxtw@forum.dlang.org)).

Yes.

> ```d
> // Catch-all arm (typeless parameter matches any variant)
> auto fallback = val.match {
>      (int i) => i,
>      (other) => -1  // matches bool and string
> };
> ```
>  From https://gist.github.com/ 
> rikkimax/0ce50c459b1635a05c9de02fe44e2aee#match-expression-syntax.
> 
>  From the context I assume `val` is a `__sumtype(int | bool | string)`. 
> So the code above is equivalent to:
> 
> ```d
> auto fallback = val.match {
>      (int i) => i,
>      (bool other) => -1,
>      (string other) => -1
> };
> ```

Yes.

> I think that needs to be specified in the DIP. There should be a 
> rationale too.
> 
> Also, `(ref other) => expr` could be supported.
There is a test for this.

```d
     rt.match
     {
         (int x) => 0, (ref y) => (y = false, 0) // catch-all ref on 
bool variant: y is ref bool
     };
```



More information about the dip.development mailing list