On Jan 31, 2012, at 10:22 AM, Brendan Eich wrote:

>> Allen Wirfs-Brock <mailto:[email protected]>
>> January 31, 2012 9:20 AM
>> 
>> But it's an issue that I'ver been thinking about since the last meeting.
>> 
>> The basic difference between non-strict direct eval and strict direct eval 
>> is that strict creates a new nested environment contour that is used as both 
>> the VariableEnvironement and LexicalEnvironment while non-strict uses the 
>> currently active Variable/Lexical environment.
>> 
>> It there are two possible semantics for non-strict eval with lexical 
>> declaration that I have come up with are:
>> 1) same as ES5, it currents it uses/extends the current Variable and Lexical 
>> Environments
>> function f() {
>>   // variable environment
>>   function xVarEnv() {return x}
>>   {
>>      //lexical environment
>>      print(xVarEnv());  //should be: undefined
>>      eval("var x=1");    //create in the variable environment
>>      print(xVarEnv());  //should be: 1
>>      eval("let x=2");     //create in the lexical environment
>>      eval("print(x)")     //should be: 2
>>      print(x);                 //should be: 2
>>      print(xVarEnv()); //should be: 1
>>   }
>>   print(xVarEnv()); //should be: 1
>> )
>> 
>> (note that the most interesting example have an inner block)
> 
> (Indeed.)
> 
> I don't like this because we make a pre-strict variation on 'let' that 
> perpetuates the dynamic scope injection flaw in eval, whereby it can pollute 
> its caller's scope with fresh bindings. This is just evil and I wish we'd 
> never standardized it in ES1 for 'var'. I see no good coming from extending 
> it to 'let' and 'const'.
> 
> And 'function' in block? That's a different case again because it wouldn't 
> hoist. Indeed direct eval('function f(){...}') in non-strict code is 
> analogous to the SpiderMonkey conditionally-compiled, dynamically-bound 
> function in sub-statement pre-ES3 extension we are trying to kill.

To further clarify, consider this valid ES5 code that must continue to produce 
the same result in ES6 :

function f(condition,body1,body2) {
   if (condition) {
       var code = "function f() {+body1+"}";
       eval(code);
   } else {
       var code = "function f() {+body2+"}";
       eval(code);
   }
   f();
}

If eval was scoped exactly like a block, then this would fail because each 
function declarations would be block scoped to  a new block scope that was 
inaccessible at the actual call site. To get the necessary compatible behavior 
we have to hoist the function out of the block scope created for the eval all 
the way up to the body scope (the Variable Environment) of the function, just 
like var.  This is will be an additional, scoping variation for function 
declarations  that only comes into play for non-strict evals. 

Allen



_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to