Second draft: Sum Type by Struct

Nick Treleaven nick at geany.org
Mon Sep 7 10:04:00 UTC 2026


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.

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)).

```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
};
```
I think that needs to be specified in the DIP. There should be a 
rationale too.

Also, `(ref other) => expr` could be supported.

> Which is the same mechanism with a lambda which hasn't got all 
> the parameters fully specified. But unlike the lambda, this 
> doesn't use templates to do it.

I suppose `(Identifier) => Expression` is a template lambda, so 
this behaviour could be considered consistent with those.


More information about the dip.development mailing list