zth/rescript-relay

[RFC] Enums as regular variants

zth opened this issue · 0 comments

zth commented

This is a RFC for a feature we could put in a new major of RescriptRelay. Think of it as a "RescriptRelay 2.0", where we have more wiggle room to introduce breaking changes.

With ReScript v11 allowing to customize the runtime representation of regular variants, we'll have opportunity to move enums from polymorphic variants to regular variants zero-cost.

What as previously:

type enum_OnlineStatus = private [ #Online | #Offline | #idle]

Would now be:

@unboxed type enum_OnlineStatus = Online | Offline | @as("idle") Idle | FutureAddedValue(string)

Pro's:

  • Much better error messages thanks to variants being nominal.
  • Will allow us to propagate comments/docs from the schema to the enum values.
  • Natural handling of the "future added value" case (the server can add new enum values to the enum before we have a chance to deploy new code handling it), using built-in language features (FutureAddedValue(string) in unboxed variants), as opposed to the current private hack that enforces handling the default case, but comes with a bunch of down sides.
  • The above point means we get back exhaustive checking for newly added enum values, something we've sacrificed with the current representation.

Con's:

  • The name of the enum value might not 100% correspond to the one in the schema, because of the naming rules for variants.
  • Can't think of one now, but I'm sure one could dig up benefits from polyvariants being structural rather than nominal.

As for migration, we'll need to figure out a good way to allow easy migration from the old to the new representation. This is of course a top priority and while publishing this under a new major RescriptRelay 2.0, I'd never just push out stuff without having a clear idea of how to migrate to it as easily as possible.

What are your thoughts on the above?

If there's anything unclear in the points I make, please feel free to ask and I'll clarify.