But it creates a lot of boilerplate not to have it. It's a feature of lots of earlier languages. Pascal, Modula-2, Ada had them (for example) too.
I really understand the need not to have unnecessary stuff, but boilerplate must be removed as well. If you look at the Stmt classes - those are tagged unions and there is a (boilerplate) method to look at what type it is (is it type X?) and if so, allow it to be cast into that particular type.
Look at the many examples here:
https://en.wikipedia.org/wiki/Tagged_unionIf you look at Pascal, the discriminator tag is very explicit:
type shapeKind = (square, rectangle, circle);
shape = record
centerx : integer;
centery : integer;
case kind : shapeKind of
square : (side : integer);
rectangle : (length, height : integer);
circle : (radius : integer);
end;
Something similar could be a minimal C2 extension:
type enum ShapeKind {
SQUARE,
CIRCLE,
RECTANGLE
}
type Shape struct {
i32 centerX;
i32 centerY;
ShapeKind kind;
union (kind) {
case SHAPE:
i32 side;
case RECTANGLE:
i32 length, height;
case CIRCLE:
i32 radius;
}
}
This should be iterated a few times
type Shape struct {
i32 centerX;
i32 centerY;
i8 kind; // Just like this? Have the enum be implicitly created?
union (kind) {
square: { i32 side; }
rectangle: { i32 length, height; }
circle: { i32 radius; }
}
}
It removes some with manual tagged unions:
1. Boilerplate is removed
2. The tag is explicitly linked to the union - good for code reading.
3. It has automatic update of the tag when accessing union fields, this removes a source of errors.
4. The compiler can analyse and make better warnings.
5. In the debug builds, the compiler can insert a check to warn when a union field is accessed when the type is different.
Note that everything can be done extremely straightforward here. The only "magic" is the dual update of tag and union value during write (shape.radius = 10 makes the shape a circle). Even that can be dropped actually. I think the most important parts are 1, 2, 4, 5. The uses of automatic tag updates can definitely be questioned.