"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:
"We shouldn't encourage this, using objects is slower than records!" π€·ββοΈ ppl are gonna have to learn the pros/cons between objects and records sometime. Objects are super useful for js interop, and in many cases doing a clone+update of a js object that you already have will be faster than converting to a record and then updating it...
"Immutably updating" a js object (creating a new copy w/ some fields changed) is currently quite cumbersome and not terribly type safe.
Proposed syntax (mirrors record update):
This would desugar to
This also requires a new function,
clone
, in the bucklescript std library. It couple implemented as:Possible objections:
cc @chenglou @bobzhang