You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Requested on Discord by Bert. There is currently no Var operation for structural (deep) equality. Var.__eq__ compiles to a JS identity comparison, so two structurally identical dicts never compare equal on the frontend:
The request is for a Var operation equivalent to lodash's isEqual: deep structural comparison of objects/arrays/primitives, returning a BooleanVar usable anywhere on the frontend.
Purpose: compare two state-derived structures on the frontend, without round-tripping to the backend and without hand-rolling a comparison per data shape.
Use case (from the reporter): a form that highlights each field that differs from what was previously submitted. Most fields are scalars, so previous == current is enough. One field is a PaintScheme — a mapping of house element to the color chosen for it, picked from a catalog. Changing the whole scheme is a cheap id/name comparison, but changing individual element colors within a scheme means comparing the entire nested mapping against the previously submitted one. The form is data-driven — the same code renders many different form configurations and item types, of which PaintScheme is one — so a hard-coded per-shape comparison isn't available.
Current workaround
Since reduce landed (#6701), this can be built by hand: iterate the keys, & together the per-key comparisons.
The reporter notes this took about half an hour to work out and explicitly is not claiming there's no alternative — so this is an ergonomics request, not a blocker. The rough edges of the workaround:
It handles exactly one level. Each additional level of nesting needs another hand-written pass — in the reporter's case the values were ColorValue objects, so the real comparison sits one level below the key.
The explicit length() check is needed to catch keys present in only one of the two dicts; it's easy to leave off and get a false positive.
It has to be written differently again for arrays.
Additional context
Related: Extend rx.memo configuration and function memoization #7084 deep-compares memoized prop objects with .to_string() (JSON.stringify), which carries the same key-order caveat shown above. A shared deep-equality primitive could back both.
Naming: Var.equals() is already taken by a compile-time method that compares _js_expr / _var_type / _var_data (i.e. "are these the same Var?"), not runtime values. A new runtime operation should not reuse that name.
Implementation: likely a var_operation emitting a small recursive comparison helper in the JS runtime. Pulling in lodash for one function seems unwarranted; there are small single-purpose deep-equal packages if a dependency is preferred over a hand-written helper.
Describe the Features
Requested on Discord by Bert. There is currently no Var operation for structural (deep) equality.
Var.__eq__compiles to a JS identity comparison, so two structurally identical dicts never compare equal on the frontend:The obvious workaround — comparing
to_string(), i.e.JSON.stringify— is key-insertion-order dependent, so it is also false here:The request is for a Var operation equivalent to lodash's
isEqual: deep structural comparison of objects/arrays/primitives, returning aBooleanVarusable anywhere on the frontend.Purpose: compare two state-derived structures on the frontend, without round-tripping to the backend and without hand-rolling a comparison per data shape.
Use case (from the reporter): a form that highlights each field that differs from what was previously submitted. Most fields are scalars, so
previous == currentis enough. One field is aPaintScheme— a mapping of house element to the color chosen for it, picked from a catalog. Changing the whole scheme is a cheap id/name comparison, but changing individual element colors within a scheme means comparing the entire nested mapping against the previously submitted one. The form is data-driven — the same code renders many different form configurations and item types, of whichPaintSchemeis one — so a hard-coded per-shape comparison isn't available.Current workaround
Since
reducelanded (#6701), this can be built by hand: iterate the keys,&together the per-key comparisons.The reporter notes this took about half an hour to work out and explicitly is not claiming there's no alternative — so this is an ergonomics request, not a blocker. The rough edges of the workaround:
ColorValueobjects, so the real comparison sits one level below the key.length()check is needed to catch keys present in only one of the two dicts; it's easy to leave off and get a false positive.Additional context
.to_string()(JSON.stringify), which carries the same key-order caveat shown above. A shared deep-equality primitive could back both.Var.equals()is already taken by a compile-time method that compares_js_expr/_var_type/_var_data(i.e. "are these the same Var?"), not runtime values. A new runtime operation should not reuse that name.var_operationemitting a small recursive comparison helper in the JS runtime. Pulling in lodash for one function seems unwarranted; there are small single-purpose deep-equal packages if a dependency is preferred over a hand-written helper.