In this proposal I propose a third sumtype design, one in which it is based upon structs.
Paul's design is based upon union's, and Walter's is on enum's.
This completes the triple axis that sumtypes live on.
Latest: https://gist.github.com/rikkimax/35b5673554e8d15fc3710082953989fb
Matching is supported by this proposal, with full capability. It uses DIP1048, along with another proposal in the development forum the member-of-operator.
Tag names are optional, if you use the member-of-operator to define an element you cannot provide a name as it is already unique.
The layout of the sumtype is variable size, allowing for copy constructors, destructors and no value (if size zero).
There is also one other unique behaviour, the ability to act as an alias this
, when only one element is in the constraint set. Very useful behaviour for returning values with a match.
I do have three core goals in this design:
- Make it very easy to swap from a library design to a language sumtype.
- Allow value type exceptions to be baked by this, and to offer catch all.
- Easy for non-D programmers to learn and utilize this as a feature without changing their mental model. As a concept this has changed very little over the last 50 years, we do not need to invent a new set of design parameters.
sumtype S = :None | int;
sumtype S2 = int | bool;
S1 s1;
S2 s2 = s1.match {
(:None) {
if (random() > 0.5)
return true;
else
return 2;
};
(int v) {
return v;
};
};
To access an element value in @system
code use casting. Assigning is @safe
.
sumtype S = int i | bool;
S s;
cast(:i)s = 2;
assert(cast(:i)s == 2);