reasonml / reasonml/reason

[feature] Add sugar for immutably updating js objects

Open
#1,471 1 comment 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Parser RFC
Dominant language
OCaml
Stars
10.3k
Forks
438
PR merge metrics
No merged PRs in 30d

Description

"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...

cc @chenglou @bobzhang

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start from the proposed object-update syntax and its desugaring in the issue, then locate the parser and syntax translation code in the Reason compiler. Also inspect the BuckleScript standard library area where Js.Obj.assign is defined to assess the proposed clone function. Done means the syntax and clone support are implemented with suitable coverage, but no files or tests are named in the issue.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, ocaml
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.