{"action":"opened","issue":{"url":"https://api.github.com/repos/bloomberg/bucklescript/issues/584","repository_url":"https://api.github.com/repos/bloomberg/bucklescript","labels_url":"https://api.github.com/repos/bloomberg/bucklescript/issues/584/labels{/name}","comments_url":"https://api.github.com/repos/bloomberg/bucklescript/issues/584/comments","events_url":"https://api.github.com/repos/bloomberg/bucklescript/issues/584/events","html_url":"https://github.com/bloomberg/bucklescript/issues/584","id":168787841,"number":584,"title":"Understanding @bs.string with variants","user":{"login":"freebroccolo","id":151197,"avatar_url":"https://avatars.githubusercontent.com/u/151197?v=3","gravatar_id":"","url":"https://api.github.com/users/freebroccolo","html_url":"https://github.com/freebroccolo","followers_url":"https://api.github.com/users/freebroccolo/followers","following_url":"https://api.github.com/users/freebroccolo/following{/other_user}","gists_url":"https://api.github.com/users/freebroccolo/gists{/gist_id}","starred_url":"https://api.github.com/users/freebroccolo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/freebroccolo/subscriptions","organizations_url":"https://api.github.com/users/freebroccolo/orgs","repos_url":"https://api.github.com/users/freebroccolo/repos","events_url":"https://api.github.com/users/freebroccolo/events{/privacy}","received_events_url":"https://api.github.com/users/freebroccolo/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-08-02T02:49:27Z","updated_at":"2016-08-02T02:49:27Z","closed_at":null,"body":"I have some OCaml code like this:\r\n\r\n```ocaml\r\nexternal on : t Js.t -> ([ `quit of (Event.t -> int -> unit [@bs]) ] [@bs.string]) -> t Js.t = \"\" [@@bs.send]\r\n```\r\n\r\nIt is used to generate Javascript code like this:\r\n\r\n```javascript\r\napp.on(\"quit\", function(event, code) {\r\n  …\r\n});\r\n```\r\n\r\nI have a couple of questions about how `@bs.string` works which I list below.\r\n\r\nFirst, `@bs.string` only seems to generate strings if the polymorphic variant types are given \"inline\", directly with the function type signature. If I try to specify a separate type, say like this:\r\n\r\n```ocaml\r\ntype event = [ `quit of (Event.t -> int -> unit [@bs]) ] [@bs.string]\r\n```\r\n\r\n… and then specify the type of `on` like this:\r\n\r\n```ocaml\r\nexternal on : t Js.t -> event -> t Js.t = \"\" [@@bs.send]\r\n```\r\n\r\n… then the code still compiles but the constructors for `event` are translated as numbers rather than strings as I would expect.\r\n\r\n**First question**: is it possible to get the constructors generated as strings for the non-inline type `event` when compiling `on`? This would make the code cleaner and easier to read I think.\r\n\r\n**Second question**: is it possible to get `@bs.string` working for extensible variants?\r\n\r\nThe case I have in mind is the `emit` method:\r\n\r\n```ocaml\r\ntype _ event = .. [@bs.string]\r\ntype _ event += Quit : int -> int event [@bs.as \"quit\"]\r\nexternal emit : t Js.t -> 'e event -> bool = \"\" [@@bs.send]\r\nval obj : t\r\n\r\nemit obj @@ Quit 0\r\n```\r\n\r\n… which should be translated like this:\r\n\r\n```javascript\r\nobj.emit(\"quit\", 0);\r\n```\r\n\r\nI think the reason you'd want to be able to do this with *extensible variants* rather than *polymorphic variants* is so that you could specify a certain set of allowed events in your application and then ensure that they are always used consistently. AFAICT this wouldn't work with just polymorphic variants.\r\n\r\n*Third question*: why does `@bs.string` with polymorphic variants (in the first example with `on`) get translated the way it does to Javascript? It appears that in the translation the arguments to the constructor are *spliced* into the arguments of the function. The way it works is very useful but I found it surprising when I first saw it. Or is that just part of the behavior of `@@bs.send`?"}}
{"actor":{"display_login":"freebroccolo"}}