-
Notifications
You must be signed in to change notification settings - Fork 463
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Status of runtime representation #6077
Comments
There are several ways in which the compilation of variants relies on tags being integers: - Sometimes it uses booleans `if x` to mean `x !=0` to mean: not the first variant (i.e. tag 0) - Sometimes it uses intervals `if (x > 3 || x < 1)` Care is required not to change the compilation of variants with special compilation: - true and false - lists have constructors "[]" and "::" - options have a specific definition for "Some" and "None" See #6077
It's unclear to me what a clean representation of variants would be, and what tags could be if not ints. Could you expand a bit on this @cristianoc? It also seems that an implication of this might be that pattern matching would be less optimized? |
One of the ideas here is that this: type stuff = User({name: string, age: int}) | Pet({age: int})
let user = User({name: "Hello", age: 35}) ...which now compiles to this: var user = {
TAG: /* User */0,
name: "Hello",
age: 35
}; ...could instead compile to this: var user = {
kind: "User",
name: "Hello",
age: 35
}; We call it "kind" here, but it could easily be called something else (maybe still
This would likely also open up being able to configure the runtime representation of payload-less variants, like: type fetchPolicy = | @as("store-or-network") StoreOrNetwork | @as("store-only") Store Also quite important, because right now we're implicitly pushing people towards using polyvariants when they need control over the runtime representation for zero cost bindings. But, a polyvariant is typically the wrong choice (structural, can't add documentation, worse error messages, etc), and most users would be better off using regular variants, but can't/won't because they'd need to do runtime conversion. |
There are several ways in which the compilation of variants relies on tags being integers: - Sometimes it uses booleans `if x` to mean `x !=0` to mean: not the first variant (i.e. tag 0) - Sometimes it uses intervals `if (x > 3 || x < 1)` Care is required not to change the compilation of variants with special compilation: - true and false - lists have constructors "[]" and "::" - options have a specific definition for "Some" and "None" See #6077
Thank for the explanation @zth! I think this makes a lot of sense for all the stated reasons. I do still worry a little bit about the performance implications though. Even if rare, it would be nice to be able to opt in to the old representation and optimizing pattern match compiler. |
For variants,
Considering between readability and efficiency, I agree with the configurable idea, just like the
As for genType, in my opinion, generating
Instead, we can use the enum in TS for TAG
|
Keep in mind the goal here is to interface with TypeScript and existing APIs. So even though an array might be more efficient, the APIs exist already, and the best one can do is to make it easy to consume them. That said, the untagged variants proposal adds one more way to control the runtime representation. |
This issue describes the current status of the runtime representation of ReScript constructs in JS.
Most constructs map cleanly to JS with some exceptions:
D(1,2)
are represented as{TAG: /* D */1, _0: 1, _1: 2}
.(int, int)=>int
could be a function with 2 args, or a function with 1 arg returning a function with 1 arg.One implication is that these representations can be cumbersome to use from JS.
Another implication is the type correspondence with genType, where in order to get a clean mapping, a runtime conversion needs to be performed. Sometimes that conversion is simply missing even with genType, e.g. in recursive types with variants where an appropriate recursive function would need to be generated. (See issues about genType and linked lists).
If one could have clean representations, then FFI would be simpler, and typed FFI with genType would require no runtime whatsoever #6099. A further implication is that one could try to move towards just generating
.d.ts
files, which fit much more naturally in a TS project.The obstacles to cleaning up the remaining cases are the following:
For example:
generates
as it relies on the fact that tags are numeric values (and is not obvious to the user how it maps to the source program).
The text was updated successfully, but these errors were encountered: