{"action":"created","issue":{"url":"https://api.github.com/repos/BuckleScript/bucklescript/issues/2680","repository_url":"https://api.github.com/repos/BuckleScript/bucklescript","labels_url":"https://api.github.com/repos/BuckleScript/bucklescript/issues/2680/labels{/name}","comments_url":"https://api.github.com/repos/BuckleScript/bucklescript/issues/2680/comments","events_url":"https://api.github.com/repos/BuckleScript/bucklescript/issues/2680/events","html_url":"https://github.com/BuckleScript/bucklescript/issues/2680","id":308852403,"number":2680,"title":"`bs.deriving abstract`: start with a record type or a creator function?","user":{"login":"chenglou","id":1909539,"avatar_url":"https://avatars2.githubusercontent.com/u/1909539?v=4","gravatar_id":"","url":"https://api.github.com/users/chenglou","html_url":"https://github.com/chenglou","followers_url":"https://api.github.com/users/chenglou/followers","following_url":"https://api.github.com/users/chenglou/following{/other_user}","gists_url":"https://api.github.com/users/chenglou/gists{/gist_id}","starred_url":"https://api.github.com/users/chenglou/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chenglou/subscriptions","organizations_url":"https://api.github.com/users/chenglou/orgs","repos_url":"https://api.github.com/users/chenglou/repos","events_url":"https://api.github.com/users/chenglou/events{/privacy}","received_events_url":"https://api.github.com/users/chenglou/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":8,"created_at":"2018-03-27T07:31:50Z","updated_at":"2018-03-29T03:35:58Z","closed_at":null,"author_association":"OWNER","body":"Here's an overview of `bs.deriving abstract` currently:\r\n\r\n```reason\r\n[@bs.deriving abstract]\r\ntype foo = {\r\n  high: int,\r\n  low: option(int),\r\n};\r\n```\r\n\r\nThis generates:\r\n\r\n- An abstract type `t`\r\n- A creator function: `let foo: (~high: int, ~low: option(int)=?, unit) => t`\r\n- Getters: `high`, `low`\r\n- Setters: `highSet`, highLow`\r\n- The original record type is erased\r\n- You can annotate the labels to make the creation function/getter/setter use a different name that's otherwise invalid, e.g. `high(s)` might compile to `s[\"aria-high\"]`.\r\n- Marking a record field as mutable generates the correct setter that mutates.\r\n\r\nThe goal is that we get some nice helpers, but also that it can generate platform-agnostic code. E.g. for JS backend, we can compile that abstract type to a JS object.\r\n\r\nThe other option is to start with a creator function:\r\n\r\n```reason\r\n[@bs.deriving abstract]\r\nlet foo = (~high: int, ~low: option(int)=?, unit) => \"\";\r\n```\r\n\r\nAnd generate the same helpers. This one has some advantages:\r\n\r\n- It's clear which labels are optional. Front-end might use a lot of optional args. In the current record-based deriving, if you write `low: foo` you wouldn't know whether `foo` is `option(int)` and accidentally make `low` non-optional.\r\n- You get to specify default values. This is limited, but nice.\r\n- You can customize the body of the function for future purposes.\r\n- The function name is customizable.\r\n- Likely less confusing for newcomers, because the first one has a record type which cannot be used (it's erased). So no weird errors when trying to create a value of that record type.\r\n\r\nThe drawback is that you for mutable field you'd need a new annotation.\r\n\r\nI feel that the creation-based option might make more sense, but I'm not too sure."},"comment":{"url":"https://api.github.com/repos/BuckleScript/bucklescript/issues/comments/377110727","html_url":"https://github.com/BuckleScript/bucklescript/issues/2680#issuecomment-377110727","issue_url":"https://api.github.com/repos/BuckleScript/bucklescript/issues/2680","id":377110727,"user":{"login":"chenglou","id":1909539,"avatar_url":"https://avatars2.githubusercontent.com/u/1909539?v=4","gravatar_id":"","url":"https://api.github.com/users/chenglou","html_url":"https://github.com/chenglou","followers_url":"https://api.github.com/users/chenglou/followers","following_url":"https://api.github.com/users/chenglou/following{/other_user}","gists_url":"https://api.github.com/users/chenglou/gists{/gist_id}","starred_url":"https://api.github.com/users/chenglou/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chenglou/subscriptions","organizations_url":"https://api.github.com/users/chenglou/orgs","repos_url":"https://api.github.com/users/chenglou/repos","events_url":"https://api.github.com/users/chenglou/events{/privacy}","received_events_url":"https://api.github.com/users/chenglou/received_events","type":"User","site_admin":false},"created_at":"2018-03-29T03:35:58Z","updated_at":"2018-03-29T03:35:58Z","author_association":"OWNER","body":"I guess at least you can merge default value and bs.optional? Don't want too many new tags"}}
{"actor":{"display_login":"chenglou"}}