Refutable destructuring

Allen Wirfs-Brock allen at
Fri Aug 16 12:56:23 PDT 2013

On Aug 16, 2013, at 12:18 PM, Dmitry Soshnikov wrote:

> On Fri, Aug 16, 2013 at 11:26 AM, Kevin Smith <zenparsing at> wrote:
> And for the strict match one could introduce match(...) function which already would throw providing exactly matching procedure first, and then destructuring as a consequence.
> Do you not think that it would be awkward to have the exact same pattern syntax for these two cases (matching and destructuring), but with different semantics?
> Yes, I don't think so. Also, this exact (or strict, or refutable if you will) matching I'm proposing as addition. And for this it's good to have a very good practical use-case and a reason. Do you know such practical use-cases today when people need strict match with throwing? How widely they are used?
> tl;dr:
> In immutable state languages, there is no assignment operation, there is only "binding-and-matching" operation. Which means an unbound variable can be bound once, and all other "assignment" operations already pattern matching operations -- they can only check whether the LHS matches to what is on RHS.
> ...
> In JS, there is mutation and assignment. And pattern matching here is secondary. Initially exactly the destructuring plays main role here. And again, for the current foo.nonExisting being undefined use-case is also leans towards not throwing.

In JS we also have binding initialization:

let x; // outer x
//in this zone outer 'x' is shadowed by the uninitialized inner 'x'.  any reference to 'x' will throw
let x=42;    //initialize the inner 'x' binding to the value 42
//In this zone a reference to 'x' returns the current value of inner 'x'

In ES6 a reference to 'x' is always valid if it is dominated by a single name lexical declaration of 'x'.  If we want to preserve this for destructuring initialized bindings we must deal with:

let {x} = {};

More specifically, we don't want to allow control to pas such a declaration without initializing the local binding for 'x'.  So our alternatives are initialize 'x' to undefined as if it was a single name binding without an initializer or throwing to stop forward progress.

I think either would be acceptable.  However, I think throwing is like to reveal bugs that might otherwise be missed prior to deployment and as a code reader I would prefer to encounter
   let {x=undefined) = {};
which communicates much more clearly that there is an expectation that 'x' may not exist as a property of the RHS.

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

More information about the es-discuss mailing list