On dropping @names

Andreas Rossberg rossberg at google.com
Thu Dec 27 01:23:44 PST 2012

On 27 December 2012 01:50, David Herman <dherman at mozilla.com> wrote:

> On Dec 11, 2012, at 2:45 AM, Andreas Rossberg <rossberg at google.com> wrote:
> > 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:

I think nobody ever proposed going for this semantics, so we can put that
aside quickly. However:

>     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) { ... }

That is not actually true, because AFAICT, "let x" was always understood to
be equivalent to "let x = undefined".

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`.

There is not just 'let' and 'const' in ES6, but more than a handful of
declaration forms. Even with everything else not mattering, I think it
would be rather confusing if 'let' had a different semantics completely
different from all the rest.

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.

As Dominic has pointed out already, this is kind of a circular argument.
The only reason you care about this for 'var' is because 'var' is doing
this implicitly already. So programmers want to make it explicit for the
sake of clarity. TDZ, on the other hand, does not have this implicit
widening of life time, so no need to make anything explicit.

It's true that with TDZ, there is a difference between the two forms above,
but that is irrelevant, because that difference can only be observed for
erroneous programs (i.e. where the first version throws, because 'x' is
used by 'stmt').

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20121227/70a5aa97/attachment-0001.html>

More information about the es-discuss mailing list