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