Inconsistent evaluation order in destructuring assignments

# BelleveInvis (12 years ago)

In ES5 all assignments are evaluated following this formula: get a reference via evaluating LHSget a value through evaluating RHSassign the value to the reference However in the current draft, destructuring assignment are evaluated in another order which is (as seen in section 12.13.3) get a value via evaluating RHSparse LHS patternbring parts of RHS into the LHS subpatterns this causes an inconsistency that in expression [f().x] = [g()], g is called BEFORE f. That is weird, and differ from f().x = g() where g is called after f.

# Brendan Eich (12 years ago)

Yes, this is intentional and goes all the way back to ES4's original destructuring proposal, based on array-pattern destructuring implemented in Opera's Futhark engine. See

discussion:destructuring_assignment#contrast_to_normal_assignment

We want destructuring to be simple: to desugar from let {x, y} = pt; to let x = pt.x, y = pt.y (but with pt evaluated once only, of course).

# Allen Wirfs-Brock (12 years ago)

On Oct 18, 2013, at 12:24 PM, BelleveInvis wrote:

...this causes an inconsistency that in expression [f().x] = [g()], g is called BEFORE f. That is weird, and differ from f().x = g() where g is called after f.

but consider

[f().x, h().y] = g();  //assume g() evaluates to an array-like object (and intentionally removed the RHS array literal)

even if evaluation of the RHS was delayed until after evaluating the first LHS element, g() would still be evaluated before h(). You might consider evaluating all of the LHS elements to References before evaluating the RHS. That could require accumulating an arbitrary large number of pending References and it wouldn't work for object destructurings. For example:

{x:  f().x=_=>{throw "no x"}(),  h().y} = getPoint();