Open vi013t opened 4 months ago
Tagged unions are now taking over the either
keyword. I have yet to decide what enum
s will be called. Also, I wonder if it'd be handy to support a mix like Rust, where some variants can have values and some won't. This can be handy, but I'm not sure if I'd want to complicate either enums or tagged unions, or make an entirely new syntax.
One of the core features of Cabin should be tagged unions. There are many different styles to implementing tagged unions, but I'm leaning towards non-nested type unions. For example, to declare a union that can have a value of type
T
or typeE
, you'd simply have something likeT | E
, with no named fields, that you can pattern match on.A final keyword has not been decided on this yet, but one consideration is
oneof
. The syntax might look like this:The function/field syntax here is a little strange, since the declaration is fundamentally different from a union variant. One possible solution is separating this kind of thing into something like a Rust
impl
block, but then we should probably do the same forgroups
for consistency, and I'm not sure if I love that idea. Regardless, it's a possibility. Another idea is we can use named union fields, which may be more consistent:However, this often ends with deeply nested confusion and complex destructuring. This very compiler suffers from this, in which you may find
Statement::Expression(Expression::Literal(Literal(LiteralValue::Group(group), 0)))
on more than one occasion.Alternatively, we can keep it simple with a pipe:
However, this has some limitations. Firstly, it puts the generic parameter on the name of the variable, which is inconsistent with how groups and functions work. Secondly, there's no obvious way to add functions or "static" fields onto this.