Enums - #232
Conversation
|
I would love if user-defined Enums were supported, but Roblox also has Enums. Would this pose any problems for this feature being used for Roblox development and can they be solved or avoided? |
|
This would be useful as an alternative/sugar for unions of classes, but I highly dislike the restrictions on data types. These should be like Rust enums instead, where variants have a name and carry data, paving the way for nominal pattern matching: enum HttpResult
variant Success: {
code: number,
headers: { [string]: string },
body: string,
}
variant Error: {
code: number,
headers: { [string]: string },
body: string,
}
variant IoError: string
variant Timeout: {
which: "Global" | "Per-Call" | "RecvBody" | "RecvHeaders",
configured: Duration,
}
variant Other
function is_ok(self)
if enum.isvariant(self, HttpResult.Success)
return true
end
return false
end
endAlternatively, each variant could be a class instead of holding a structural data primitive whose shape can differ at runtime. |
|
What I was going for here was "enum" in the sense of "enum of constant values" akin to what you'll find in TypeScript, Python, Java, C#, etc. What you're proposing there feels like it could be represented just as well using a union of class types. If the nominal nature isn't required, it's already entirely possible using a union of table types. The data-type restrictions are part of the "constant value" semantics. The two exceptions to that are |
I've just added a note in the top comment of the PR regarding this (as Roblox-specific semantics don't feel like they fit in the RFC body). Provided the internal implementation of |
Rendered
This is very much still in-draft, but I figured I'd put it out there to get feedback sooner rather than later :)
Some comments regarding Roblox-specific details, omitted from the RFC body due to being Roblox-specific, but worth noting:
The "efficient serialisation" discussed in this RFC is focused primarily on the ability for enums to function properly when using them on Roblox in places such as a
RemoteFunction.The restrictions presented here allow for static analysis of a workspace to identify and tag all present enums (such as during publishing). Each enum can then be globally represented across both client and server code by means of its unique tag. This can then be used for an incredibly efficient network packing.
We can consider an over-the-wire format such as:
0 [20 bit: tag] [11 bit: index in enum](32-bit compact format)1 [20 bit: tag] [43 bit: index in enum](64-bit extended format)With a packing such as this, we can now efficiently support up to 1,048,576 unique enums across a codebase with up to 8,796,093,022,208 members per enum (a ridiculous amount). The extended format could also be restricted to only 48 bits in total, which still permits up to 134,217,728 members per enum. The compact format still permits 2048 members per enum.
One could imagine other over-the-wire packings using a similar approach that greatly benefit from the restrictions imposed in this RFC.
Roblox already exposes the
EnumandEnumItemdatatypes. Whether these existing engine datatypes are unified with theenumandenumitemprimitives proposed here is intentionally outside the scope of this RFC and would be an embedder decision.However, the runtime representation should ideally avoid unnecessarily preventing such unification. In particular, the implementation should consider allowing embedders to associate metatables or otherwise provide embedder-specific behaviour for enum objects and enum items. The
vectorprimitive vs Roblox'sVector3comes to mind as an example of why this consideration is required during initial implementation.This RFC does not require custom metatables to be exposed to Luau programs, nor does it require Roblox to unify the two families. It only recommends avoiding implementation constraints that would make future integration impossible.