Skip to content
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

feat: add js_{weakset,weakmap} functions #1058

Merged
merged 3 commits into from
Mar 28, 2024

Conversation

tatchi
Copy link
Contributor

@tatchi tatchi commented Feb 7, 2024

This adds js_{set,wekset,weakmap} functions copied from https://github.com/rescript-association/rescript-core

external make : unit -> 'a t = "Set" [@@mel.new]
external fromArray : 'a array -> 'a t = "Set" [@@mel.new]

(* commented out until Melange has a plan for iterators
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's not a bad idea. Looks minimal enough to do what we'd want at first.

@tatchi
Copy link
Contributor Author

tatchi commented Feb 7, 2024

Oops, I just noticed that there's already a PR for Js.set #1047 (comment) 🙈

Copy link
Member

@anmonteiro anmonteiro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is great, thanks so much!

Next steps here are:

@@ -1,3 +1,20 @@
(** ES6 Set API *)

type 'a t

external make : unit -> 'a t = "Set" [@@mel.new]
external fromArray : 'a array -> 'a t = "Set" [@@mel.new]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like fromArray, which I haven't included in #1047. would you like to make that change to my PR?

external make : unit -> 'a t = "Set" [@@mel.new]
external fromArray : 'a array -> 'a t = "Set" [@@mel.new]

(* commented out until Melange has a plan for iterators
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's not a bad idea. Looks minimal enough to do what we'd want at first.

Copy link
Member

@anmonteiro anmonteiro left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just need to remove the Js.Set files from this PR now

@tatchi tatchi changed the title feat: add js_{set,weakset,weakmap} functions feat: add js_{weakset,weakmap} functions Feb 14, 2024
@@ -1,3 +1,8 @@
(** ES6 WeakSet API *)

type 'a t

external make : unit -> 'a t = "WeakSet" [@@mel.new]
external add : value:'a -> 'a t = "add" [@@mel.send.pipe: 'a t]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw this is not 100% safe becausevalue must be an object. Trying to add a primitive value like an int fails.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so should we make it take a _ Js.t or a _ Js.Dict.t instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know. If I'm not mistaken, this means it would not be possible to pass normal OCaml record while I guess it should be ok since they compile to JS objects. See example 1097608 (#1058)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's fair, but at least with _ Js.t we can know that it's exactly a JS object.

To me, the tradeoff here seems like:

  • if you keep 'a, you can pass any argument to the functions in the module, at the cost of runtime errors when you pass non-object arguments
  • if you enforce _ Js.t, then you lose the ability to pass some well-known-to-work types (such as records, which are nominal, and you can't make a function accept "all records")

Personally, I'd prefer if we shipped 99% runtime-free, correct-by-construction code. IMO it's also pretty easy to change it downstream:

  • include the Js.WeakMap module and overwrite the externals you wish to change signatures
  • use external toJsDotT: myRecord -> _ Js.t = "%identity" to convert your records / other types that compile to objects at the boundary so that you can pass them to Js.WeakMap.

What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't use Js.t because the Js module is not accessible from jscomp/runtime and I couldn't find an alternative in Js_*. So I ended up using Js_dict.t.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's a fair compromise.

external get : key:'k -> 'v option = "get" [@@mel.send.pipe: ('k, 'v) t]
external has : key:'k -> bool = "has" [@@mel.send.pipe: ('k, 'v) t]

external set : key:'k -> value:'v -> ('k, 'v) t = "set"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, key must be an object

@tatchi tatchi requested a review from anmonteiro February 14, 2024 15:49
@@ -25,3 +25,13 @@
(** ES6 WeakMap API *)

type ('k, 'v) t

external make : unit -> ('k, 'v) t = "WeakMap" [@@mel.new]
external get : key:'k Js.dict -> 'v option = "get" [@@mel.send.pipe: ('k, 'v) t]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm, I guess this could also take a function reference instead of an object, but foregoing that is probably fine for now, as to avoid complicating the API too.

@anmonteiro anmonteiro merged commit cbd9180 into melange-re:main Mar 28, 2024
4 checks passed
@anmonteiro
Copy link
Member

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants