On Dec 11, 2012, at 2:45 AM, Andreas Rossberg <[email protected]> wrote:

Late to the party, sorry. First, let's be clear there are a couple possible 
semantics that could be called "temporal dead zone." At this point I'm not sure 
what various people had in mind; I suspect different people may have understood 
it differently.

* Read-before-assignment error (TDZ-RBA):

Any read of the variable before it has been assigned throws an error. It can be 
assigned anywhere, either in the declaration's initializer or in any other 
assignment expression. If control executes a declaration without an 
initializer, it leaves the variable in the uninitialized state.

* Use-before-initialization error (TDZ-UBI)

Any read or write of the variable before it has been assigned by its 
initializer throws an error. It can only be initially assigned by its 
initializer. If control executes a declaration without an initializer, it 
leaves the variable initialized to `undefined`.

> The question, then, boils down to what the observation should be: a
> runtime error (aka temporal dead zone) or 'undefined'. Given that
> choice, the former is superior in almost every way, because the latter
> prevents subtle initialisation errors from being caught early, and is
> not an option for most binding forms anyway.

You only listed good things (which I agree are good) about TDZ, but you don't 
list its drawbacks. I believe the drawbacks are insurmountable.

Let's start with TDZ-RBA. This semantics is *totally untenable* because it goes 
against existing practice. Today, you can create a variable that starts out 
undefined and use that on purpose:

    var x;
    if (...) { x = ... }
    if (x === undefined) { ... }

If you want to use let instead, the === if-condition will throw. You would 
instead have to write:

    let x = undefined;
    if (...) { x = ... }
    if (x === undefined) { ... }

Not only does that look superfluous to existing JavaScript programmers, since 
they never had to write that out before, but *their code will be rejected by 
JSHint*. That's actually flagged as bad practice. We cannot and must not 
introduce new constructs that *require* programmers to use idioms that have 
already been rejected by the community.

OK, so now let's consider TDZ-UBI. This now means that an initializer is 
different from an assignment, as you say:

> They are initialisations, not assignments. The difference, which is
> present in other popular languages as well, is somewhat important,
> especially wrt immutable bindings.

For `const`, I agree that some form of TDZ is necessary. But `let` is the 
important, common case. Immutable bindings (`const`) should not be driving the 
design of `let`. Consistency with `var` is far more important than consistency 
with `const`.

And for `let`, making initializers different from assignments breaks a basic 
assumption about hoisting. For example, it breaks the equivalence between

    { stmt ... let x = e; stmt' ... }

and

    { let x; stmt ... x = e; stmt' ... }

This is an assumption that has always existed for `var` (mutatis mutantum for 
the function scope vs block scope). You can move your declarations around by 
hand and you can write code transformation tools that move declarations around.

It's certainly how I understand hoisting in JavaScript, and it's how I describe 
it in my book:

    http://gyazo.com/df93d0944dff0d9487b81c3cf6802e92

In fact, Doug has taught countless programmers to hoist their declarations to 
the beginning of their function, and many (perhaps including Doug?) will 
probably do the analogous this with let, manually hoisting them to the 
beginning of the block. This transformation will actually defeat the error 
checking, since the variables will then become initialized to `undefined`.

I imagine your reply is: don't do that transformation; place your `let` 
declarations as late as possible before they are going to be used. I guess I 
need to be convinced that the equivalence is of no value.

Dave

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to