Describe your feature
Recently enums were modified to be wrapped in ()
instead of {}
due to ambiguity issues with structs. This change would remove ambiguity issues by using keywords, and would expand the capabilities of zap.
These changes are breaking changes, but are incredibly beneficial and expand the capabilities of Zap. This early into development these breaking changes are acceptable.
Reworked Structs
Currently structs are defined as such:
type t = {
fieldName: fieldTy,
}
The proposed new syntax would add a struct
keyword in front of the opening brace:
type t = struct {
fieldName: fieldTy,
}
While this is a regression in terms of concise syntax, it enables enums to use braces which will remove confusion around parens being used for type constraints.
Reworked Enums
Currently enums are defined as such:
The proposed new syntax would add an enum
keyword and replace the parens with braces:
type t = enum { one, two }
This has the same downsides and positives as the structs change, it also allows us to easily add new syntax for tagged union enums. Having empty enums is currently allowed, after this change it will be a syntax error.
Addition of Tagged Union Enums
Tagged unions are a somewhat commonly used data structure and are extremely useful for some types of data. They are comparable in structure to the Rust enum type. These tagged unions are structs consist of a field which stores the discriminant, or tag, and data that changes depending on the tag. As a luau type:
type t = {
type: "num",
value: number,
} | {
type: "str",
value: string,
}
In it's current state Zap is unable to serialize these types, although they are possible to serialize. The proposed new syntax for these kinds of types is to add a string value between the enum
keyword and opening brace: enum "type" {
, used to determine the tag field, and require a struct to be defined after each enum variant:
type t = enum "type" {
num { value: u8 },
str { value: String },
}
The tag field cannot be used inside any of the enum variant's structs. This syntax fully enables tagged unions, both the serdes and types.
Alternatives
-
The syntax enum (type) {
could have been used for tagged unions.
This syntax has the same issues with using parens for enums in the first place, it can get confused with type constraints.
-
Structs could have remained the same while only adding a enum
keyword for enums.
This would create an inconsistency between the two types, and make it slightly harder to read and for beginners to learn. Coming from a language full of inconsistencies (luau), we want to avoid these wherever possible.
-
Enums could have been top-level declarations and tagged unions would be formed by indexing enums into structs.
This still has the problem of needing to union the structs.
Implementation Details
This adds a very significant amount of complexity to the parser, and will need a new internal Ty for tagged union enums. However this shouldn't require much modification of currently existing code.
Additional context
N/A