draft proposal for Sum Types for D
Jacob Carlborg
doob at me.com
Tue Nov 29 20:37:57 UTC 2022
On Tuesday, 29 November 2022 at 06:26:20 UTC, Walter Bright wrote:
> Go ahead, Make My Day! Destroy!
>
> https://github.com/WalterBright/DIPs/blob/sumtypes/DIPs/1NNN-(wgb).md
### ABI
I think a section on ABI is missing. It should specify the memory
layout of sumtypes, just as for existing language constructs [1].
What's even more important than the memory layout is the value of
the tag. Something needs to be specified in regards to the value
of the tag. One needs to be able to draw some conclusions about
what happens with the value if members are added, removed or
reordered. Ideally the tag value of existing members should not
change. These are important things when using sumtypes at ABI
boundaries.
### Checking of the Tag
The DIP mention there's a runtime check of the tag, but it
doesn't specify what "runtime check" is. It should. Walter did
reply to a post that it would be like a buffer overflow error
[2]. Which is not entirely clear, but if you overflow a buffer
(an array) it throws a RangeError, so I would guess it throws an
Error. Yet another language construct that a has a non-obvious
dependency on the exception handling system. This is unfortunate.
The sumtype is a good alternative for error handling to the
existing exception system we have today. If the sumtype is going
to depend on the exception system this will be less attractive. A
tagged union can be used in any system (embedded, kernel, etc.).
If the sumtype is going to depend on the exception system it
probably cannot be used in these environments.
It would be great if there was no hidden runtime check. Force the
user explicitly write code that checks the tag, otherwise it's a
compile time error to access a member. Timon already suggested
this [3].
This could potentially be extended to allow accessing the field
without checking the tag, but require checking the tag before
using the value, example:
```d
sumtype Result
{
Error,
int Value
}
Result foo();
void bar()
{
auto value = foo().Value; // ok, has not been used yet
writeln(value); // compile time error to use `value`
if (!?value)
return;
writeln(value); // ok, `value` has been checked above
}
```
This would allow early returns and avoid nesting all code in if
statements. BTW, `value` now behaves more or less like an
optional type.
### Breaking Changes
Another breaking change, perhaps an edge case, but code that
inspects all types and language constructs and performs different
actions, i.e. a serialization library or something like
`writeln`. Example:
```d
static if (is(T == int)) {}
else static if (is(T == enum)) {}
// exhaustive checks of all language constructs
else
static assert(false);
```
Or even worse, if the else statement is missing.
### Switch Statement/Pattern Matching
The DIP mentions that pattern matching is subject of another DIP.
But I think it's reasonable that the switch statement should
support sumtypes, in the same way as the if statement. Nothing
fancy, just the same feature as the if statement supports.
[1] https://dlang.org/spec/abi.html
[2] https://forum.dlang.org/post/tm4kbe$23l2$1@digitalmars.com
[3] https://forum.dlang.org/post/tm55o9$mq2$3@digitalmars.com
--
/Jacob Carlborg
More information about the Digitalmars-d
mailing list