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