return when desugaring to closures
Brendan Eich
brendan at mozilla.com
Mon Oct 13 15:04:12 PDT 2008
On Oct 12, 2008, at 12:48 PM, Yuh-Ruey Chen wrote:
> Now that I think about it, would it truly be necessary for lambda to
> create an implicit block scope in the first place? |lambda() return
> 10|
> would not require such a block scope.
Implementation, or optimization, detail.
> Why not have the block scope only
> created if there are curly brackets?
What about the lambda's formal parameters? They are in scope. Would a
braced body of the lambda be able to shadow them, uselessly?
Per ES1-3, in
function f(x) { var x; ... }
the var has no effect, since x is a property of the variable object
already.
After some experiments, we decided for ES4 to make let and var the
same at top level in a function or global code.
This helped avoid implementation pain: very long scripts on the web,
consisting of many statements in a row, motivate statement-wise
parsing and cumulative code generation, which is straightforward in
the absence of goto. Yet scope changes (e.g. due to a tardy rogue let
x; after thousands of statements the first of which uses x) require a
separate pass to generate the necessary block set-up code before the
first use of x.
Unifying let and var at top level also reduces the cognitive load
(number of scopes in mind) and eliminates useless name shadowing
opportunities.
But such let/var unification at top level in a function body does
leave bad old arguments[0] aliasing x in the above example, allowing
mutation of otherwise lexical let x; (change var to let and fill in
the ... with arguments[0] = 42; return x). The answer that we chose
for ES4, and the one that's already agreeable in committee for
Harmony, was "deprecate arguments by providing optional and rest
parameters".
> That would follow the precedent set
> by the rest of the language with regards to block scope with the
> exception of |for (let x...) ...|.
There is no syntactically valid way to write let x ... except as the
direct child of a body, block, or for head, in any of the complete
proposals of let declarations I've read. One implementation, JS1.7 in
Firefox 2, did misread the proposal as allowing sentences such as
if (x) let y = 42;
and hoisting y to the block containing the if statement. This bug is
fixed in JS1.8 / Firefox 3.
Some folks have expressed the strong desire for a fresh block scope
each time through a for (let x...) loop. See
https://bugzilla.mozilla.org/show_bug.cgi?id=449811
Comments (here) welcome.
/be
More information about the Es-discuss
mailing list