Open cknitt opened 15 hours ago
For null and undefined, Primitive_js_extern
is the source of truth right now
Core -> Js -> Primitive
My theory here is that Js
is more like core, unless we assume that we can add more backend other than JS later.
Core
is not really "core" because it has a lot of host dependencies. (Js, Html, Intl, etc)
The way I perceive it is that Js
is the legacy stdlib and Core
(although the name is actually not user-visible anymore) the new stdlib.
Primitive_js_extern
has more than the types themselves though.
And the question is what will the user see in hover help etc. "Primitive_js_extern" does not sound very user-friendly.
The way I prototyped it in https://github.com/rescript-lang/experimental-rescript-stdlib-build/blob/main/runtime/src/runtime_types.res, I had
Core -> Runtime_types Js -> Runtime_types Belt -> Runtime_types
Another question is the module name, if any.
Should it be Map.t
or just map
.
Same question for the existing built in types. Which ones should have their own module name.
Should it be Map.t or just map.
Js maps are not transparent in their implementation. I would never recommend treating them as primitives.
It would certainly be nice to have date
instead of Date.t
, regExp
instead of RegExp.t
and symbol
instead of Symbol.t
etc.
Like we have dict
instead of Dict.t
now.
It would certainly be nice to have date instead of Date.t, regExp instead of RegExp.t and symbol instead of Symbol.t etc.
As I mentioned in Discord before, Date
is poorly designed and soon to be replaced by Temporal
Array and list structures are simple and predictable, but map/set have much wider use cases. Whether it is a tree or a hashtable should be determined at the call site, and the only thing that the build depends on is the abstract type.
Dict is something that we already had in other forms.
Symbol is a primitive type in JS, so it is worth considering, but RegExp is just an Object with a different prototype.
IMHO we have to be very careful when choosing these. Treating something that isn't primitive as if it were a primitive is a decision we can never reverse. And it limits the quality of the implementation beyond just the interface.
Do you think Belt is no longer needed once Core bindings are provided? In fact, there are examples where Belt Map works more efficiently than Js Map.
https://github.com/cometkim/benchmark-rescript-cache-impl
We don't have to specify the properties of implementations in the language, even if Js does. I keep emphasizing the different responsibilities of primitives and stdlib.
As I mentioned in Discord before, Date is poorly designed and soon to be replaced by Temporal
I disagree that it should be the reason not to include the date
type. It's a standard of the platform, and even though it's poorly designed, it's still a primitive which is widely used.
I am not against adding widely used utilities to the standard library.
However, "widely used" does not imply the existence of primitives. Primitives are the most fundamental part of a language and have a lasting impact on subsequent designs. Beyond simply declaring built-in types, they interact with other features of the language, adding complexity and side effects of its semantic. Even with poorly designed one, they are more cumbersome to work with and lower the average quality of software written in ReScript. Especially Date
has never been progressively enhanced in ECMAScript specification. In fact, many codebases are trying to avoid relying on it and use third-party libraries like moment.js or dayjs.
There are reasons why stuffs like Date
and RegExp
are not chosen as primitives in other languages (except Raku), despite their obvious popularity.
If pattern match is possible for arbitrary constructors like Date
or RegExp
, I would ask why it is not supported for all other constructors. In most codebases, there are custom constructors that are obviously used more frequently than those.
If we support Date more conveniently because it already exists, then that is literally why people use Date. Because it is better supported, users avoid better alternatives than Date, even if they are standards driven.
This is exactly what happened between CommonJS and ESM. ESM offers a better future, but CommonJS didn't switch simply because it was work and advanced use cases.
The interoperability story is not simple, because the two specifications have distinctly different semantics. The same thing probably happens between Date and Temporal.
Currently we have e.g. in (Core) Map.res:
or in (Core) Null.res:
i.e., the
Js
modules are the source of truth.This should be changed, as
Js
should be deprecated.Two options:
Any opinions @cristianoc @zth @cometkim?