Global lexical tier

Jason Orendorff jason.orendorff at
Mon Aug 31 16:08:37 UTC 2015

Hi everyone. Can we talk about the global lexical tier?

This was a mistake, a real blunder. We all should have known better.
An extensible intermediate scope implies dynamic scoping. The referent
of an identifier can change only once, but it can change. It's like an
implicit `with` block around *all code*.

This pattern for declaring variable in multiple scripts won't work
with let/const:

    var MyES3Module = MyES3Module || {};

There's no workaround except "keep using var".

It's now possible to get a binding permanently wedged, which is bad for a REPL:

    js> let z = Maht.PI;  // oops, typo
    ReferenceError: Maht is not defined
    js> z
    ReferenceError: binding is not initialized: "z"
    js> z = 1;
    ReferenceError: binding is not initialized: "z"
    js> delete z;
    js> let z = 1;
    SyntaxError: redeclaration of variable: "z"

For a single name to have two global bindings, both mutable, is astonishing.

All of this was unnecessary. What's the benefit to users? We ran
roughshod over existing practice, invariants, and expectations in
order to obtain a kind of self-consistency for `let` that users don't
expect or even care about.

We should have just made toplevel let/const/class create global
properties, like var. This is how it was proposed originally and how
Babel implements it today. For SpiderMonkey, switching to the worse,
less user-friendly way without regressing performance is

We knew all this. We didn't evaluate it correctly. What we
particularly missed is that we already had modules as the way forward
to a nice toplevel lexical tier, and weird half measures for scripts
were pointless.


More information about the es-discuss mailing list