Toplevel 'let' binding can be left permanently uninitialized after an error

Steve Fink sphink at
Wed Nov 29 01:21:11 UTC 2017

The spidermonkey REPL shell has a special cut-out for this:

js> throw 0; let x;
uncaught exception: 0
(Unable to print stack trace)
Warning: According to the standard, after the above exception,
Warning: the global bindings should be permanently uninitialized.
Warning: We have non-standard-ly initialized them to `undefined`for you.
Warning: This nicety only happens in the JS shell.

It looks like the Firefox console does something similar, just silently. 
The Chrome console and Node REPLs wedge you permanently, from my brief 
testing. I don't have anything else within easy reach to test on.

Separately, I ran into it with a JS debugger REPL that also runs under 
the spidermonkey shell -- I have a 'run' command that reruns the 
toplevel script, which fails if you have any toplevel let/const. And the 
above cutout doesn't help; there is no error.

The bindings are created and exist, they're just set to undefined. So if 
you repeat the above line, you'll get

typein:3:1 SyntaxError: redeclaration of let x

These days, if I have a script that I might want to debug with my hacky 
debugger REPL, I'm careful to use only 'var' at the toplevel.

All REPLs and REPL-like things run into this. Perhaps it would be useful 
to agree on a common behavior? Or at least share coping strategies.

On 11/28/2017 11:59 AM, Isiah Meadows wrote:
> And this is why I use `var` instead of `let` in REPLs. They're doing 
> what they're supposed to do; it's just unintuitive.
> As a secondary proposal, I feel `let`/`const` in scripts should be 
> allowed to shadow existing globals at the top level *provided* they 
> are not declared in the same script. It'd solve the globals issue as 
> well as not require the parser to make calls to the runtime 
> environment. Of course, this means engines can't assume global `const` 
> is immutable, but they already do similar global checks, anyways (like 
> if the variable was not defined in that script).
> On Tue, Nov 28, 2017, 14:31 Joseph <pacerier at 
> <mailto:pacerier at>> wrote:
>     Re "x is irreparably hosed in your REPL"; you can still use it in
>     subscope, eg <{let x=1;console.log(1)}>.
>     On 29 November 2017 at 01:30, T.J. Crowder
>     <tj.crowder at
>     <mailto:tj.crowder at>> wrote:
>         On Tue, Nov 28, 2017 at 5:05 PM, Joseph <pacerier at
>         <mailto:pacerier at>> wrote:
>         > You can still do `{x}`.
>         Can you expand on that? It doesn't seem to me you can. I mean,
>         if even `x = 42;` won't work (,
>         I fail to see how anything else using `x` would work,
>         including `{x}` (,
> `x` is permanently in the
>         TDZ as far as I can tell.
>         -- T.J. Crowder
>     _______________________________________________
>     es-discuss mailing list
>     es-discuss at <mailto:es-discuss at>
> _______________________________________________
> es-discuss mailing list
> es-discuss at

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

More information about the es-discuss mailing list