That looks pretty good. I read through
https://en.wikipedia.org/wiki/Tagged_union. I didn't see what I was looking for until Nim's implementation. Nim is a very cool language, IMO, with some common motivations with Rune. Here's tagged unions in Nim:
enum Shape {
skSquare, skRectangle, skCircle
Shape = object
centerX, centerY: int
case kind: ShapeKind
of skSquare:
side: int
of skRectangle:
length, height: int
of skCircle:
radius: int
I like that Nim puts the tagged union in the struct/object/class rather than in the enum itself. This allows different classes/structs to assign different data using the same enum. For example, consider Color. Some use cases for this enoum might assign RGB values, but there are any number of values we might associate with color, like price, or whether a color is a given person's favorite.
I'm tempted to say we should integrate tagged unions into structs and possibly also tuples, but not classes. A class can always have a struct or tuple as a data member.
For example, maybe syntax like:
enum ShapeType { Square
Rectangle
Circle
}
struct Shape {
centerX: i32
centerY:i32
type: ShapeType
switch type {
case Square
side: u32
}
case Rectangle {
length: u32
width: u32
}
case Circle {
radius: u32
}
}
Read/write could be done normally, and an error could be thrown if accessing the wrong field for the type. Structs in Rune are already template types. For example, if we wanted to implement a Rust-like Option struct:
enum OptionType {
Some
None
}
struct Option {
type: OptionType,
switch type {
case Some {
value // Note there is no type constraint, making it a template.
}
case None {
{
}
}
This type could be used to avoid dealing with null values. If we did that, I think we'd want a more concise syntax than our current switch syntax. Rust uses something like:
match retVal {
Some(val) => return val;
None => panic!("retVal is None")
}
I've sent a CL out for review that lets us use => for one-statement cases, and also deletes the case keyword in front, so it looks more like this.