destructuring: as patterns?

Allen Wirfs-Brock allen at
Fri Apr 20 15:35:42 PDT 2012

On Apr 20, 2012, at 2:43 PM, Brendan Eich wrote:

> Allen Wirfs-Brock wrote:
>>> >  >  js>  let {y:{z}} = {};
>>> >  typein:4: TypeError: (void 0) is undefined
>> alternatively:
>>    let {y:{z} = {z:"default"}} = {};
>> or
>>    let {y:{z = "default"}} = {};
> Too verbose, for one.
>>> >  (Atrocious SpiderMonkey failure to pretty-print the blamed expression instead of its portable (void 0) value there -- my fault I think.)
>>> >  >  Dave suggested making the first case, let {x} = {}, throw, and requiring ? as a pattern modifier (I suggested prefix):
>> Then shouldn't
>>    let x;
>> be illegal?
> No. I know destructuring requires an initialiser but let does not and I think should not. It's a different beast. What you seem to be suggesting is that we relax the initialiser requirement, not that we ban let x.
>>   Would you have to say:
>>    let ?x;
> No way!

What I'm really pushing at here is the throw. Let's are  used for establishing and initializing bindings.  From a binding perspective:

    let x ;
    let {x} = {};

are almost exactly the same thing.  They both establish a hoisted uninitialized lexical binding for x.  They both delimit the end of the TDZ for x. They both supply undefined as the initialization value of x. Why should the second form throw when the first doesn't

Or, here is another way to think about it:

  let tmp1 = {};
  let x =  temp1.x;

I don't think anybody is suggesting that the above should throw on the let initialization of x.  so why should
   let {x} = {};
which is just a refactoring of the same bindings and accesses.

>>> >  let {?x} = {}; // x is undefined, no throw
>>> >  let {y} = {};  // throws
>> so, why not:
>>   let {x=undefined} = {};
> Again, too verbose

which is why we allow the "=undefined" to be left out and it don't throw.

What I think is going on in this discussion is a difference between viewing destructuuring as a shorthand (relative to the desugaring I used above) for initializing bindings and thinking of desugaring as a pattern matching operation. Desugaring isn't generalized pattern matching (see,  and ). This is quite clear when you look at what is going on from the perspective of its specification.

> and (this is the part I left out, see followup) not deep. How would defaulting work here?
>  let {x:{y:{z}}} = {};

let {x:{y:{z}} = {y:{z:"defaultZ"}}} = {};
//note that "z" is the only bound name above"

> /be

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list