Open cometkim opened 2 months ago
The downside is as mentioned in https://github.com/rescript-lang/rescript-compiler/issues/6738#issuecomment-2075174646
Using this feature can reduce interoperability with other ser/de libraries.
@cometkim could you point to a few real world examples? Not opposed the functionality, just not something I've encountered often myself.
As mentioned in the text, we already have some internal fields to protect.
It will be useful when the ReScript user wants to hide such fields or protect records from JS/TS side.
Many real-world libraries have objects with internal fields, which are marked with an underscore prefix https://github.com/search?q=_cache+language%3AJavaScript&type=code
Motivation
Customizable variants greatly enhance the experience of using ReScript records in JavaScript.
But it still lacks encapsulation capabilities. When building a library in JS, implementers can put internal values in secret fields that are not exposed to end users.
This is usually achieved through symbols.
The symbol is an effective way to protect the package's internal knowledge.
e.g. https://github.com/facebook/react/blob/a03254bc/packages/shared/ReactSymbols.js
and it can simulate other advanced features such as private fields.
This can be used as a key in any JS object. It is also suitable for use as a ReScript record key.
So I proposed #6738 to use symbols by default in all ReScript internal values, but it had issues and seems not viable.
However, it still seems useful for some cases to make this a choice for the user rather than the compiler.
Also useful for the compiler itself https://github.com/rescript-lang/rescript-compiler/blob/d9d5800f3/jscomp/runtime/caml_option.resi#L25
Design
@as(symbol)
for customizable variantsUses the same syntax as the customizable variants, but uses
@as(symbol)
as a reserved one.Emits
The values will automatically assigned with
Symbol.for({typepath})
.Symbol.for
can be used without module resolution because it is tracked by JS. So it has a fairly low implementation complexity and make it easier to debug.Symbol as tag
Or even
Symbol as value
Non-goal, as we already can use symbol as value just like normal FFI syntax.
TypeScript
genType will not generate types for fields designated as a symbol.