reasonml / reason

Simple, fast & type safe code that leverages the JavaScript & OCaml ecosystems
http://reasonml.github.io
MIT License
10.13k stars 430 forks source link

[feature] Add sugar for immutably updating js objects #1471

Open jaredly opened 7 years ago

jaredly commented 7 years ago

"Immutably updating" a js object (creating a new copy w/ some fields changed) is currently quite cumbersome and not terribly type safe.

let someObj = {"a": "1", "b": "2", "c": "3", "d": "4"};
let newObj: Js.t {a: string, b: string} = Js.Obj.assign (Js.Obj.empty ()) someObj;
/**         ^ - you have to constrain this, because Js.Obj.assign returns type `Js.t {..}` **/
newObj##a = "awesome";
newObj##d = "things";

Proposed syntax (mirrors record update):

let someObj = {"a": "1", "b": "2", "c": "3", "d": "4"};
let newObj = {...someObj, "a": "awesome", "d": "things"};

This would desugar to

let newObj = {
  let tmp = Js.Obj.clone someObj;
  tmp##a = "awesome";
  tmp##d = "things";
}

This also requires a new function, clone, in the bucklescript std library. It couple implemented as:

let clone: Js.t 'a => Js.t 'a = fun obj => Js.Obj.assign (Js.Obj.empty()) obj;

Possible objections:

cc @chenglou @bobzhang

jaredly commented 7 years ago

see also https://github.com/facebook/reason/issues/1449, if we could get nested object update that would be πŸ”₯πŸ”₯πŸ”₯