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

[@bs.as] for special BS object creation function #2614

Closed
chenglou opened this issue Mar 13, 2018 · 4 comments
Closed

[@bs.as] for special BS object creation function #2614

chenglou opened this issue Mar 13, 2018 · 4 comments

Comments

@chenglou
Copy link
Member

(* invalid syntax, bear with me for now. I dunno how to attach an attribute onto an argument label *)
external makeConfig : (high [@bs.as "high-value"]):int -> ?low:int -> unit -> _ = "" [@@bs.obj]
let c1 = makeConfig ~high:3 ()

It'd generate {"high-value": 3}.

Super useful. The special object creation is the only one that allows optional fields, so we can't directly create the objs on the Reason side through {"high-value": 3}. For example: https://github.com/reasonml/reason-react/blob/7eed3579ebfc7402eebe331b740b0a8bed4e44b5/src/ReactDOMRe.re#L95

cc @rickyvetter @thangngoc89 @yawaramin @glennsl

@glennsl
Copy link
Contributor

glennsl commented Mar 13, 2018

Love the idea, but slightly concerned about overloading the meaning of bs.as. With emphasis on "slightly" since it's already overloaded and I haven't noticed any issues with that.

@bobzhang
Copy link
Member

bobzhang commented Mar 15, 2018

The main thing is if we infer the output type still as < high : int; low : int > Js.t then the access is incorrect. If you infer it as < "high-value" : int ; low : int > Js.t, then it does not feel right to me.

The only sensible way to me is require the output to be an abstract type.

By tweaking the spec of bs.deriving abstract, we are quite close to it:

type label = {
   high : int  [@bs.as "high-value"];
   low : int [@bs.optional]; (* better name or just use `int option` *)
} [@@bs.deriving abstract]

In that case, we derive such functions:

val label : high : int -> ?low: int -> unit -> label
val high : label -> int 
val low : label -> int option

So we need implement bs.as and option support.

For bs.as, the rough idea is

external label : high:int -> low: int -> label = "xxx" (* the internal encoding changed to "high-value" *)
external high : label -> ( _ : [@bs.as  "high-value"]) -> int = "" [@@bs.get_index] 

For bs.optional, the rough idea is

external label : high: int -> ?low: int -> label = "" [@@bs.obj]
external low : label -> int = "low" [@@bs.return undefined_to_opt]

The two attributes may interact, this is quite a few work, lets make it for next release

@bobzhang
Copy link
Member

relevant to #2583

@bobzhang
Copy link
Member

Currently
type x = { hi: int} [@@bs.deriving abstract],
will generate val x : hi:int -> x, we may want to allow customize the name of constructor,
the proposed syntax:

type x = { hi: int} [@@bs.deriving {abstract = constructorName, "make"}]  

What do you think?

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

No branches or pull requests

3 participants