How about "Keyword 'let' not allowed without 'use strict' or in a module". ?


On Fri, Feb 14, 2014 at 8:18 AM, Mark S. Miller <erig...@google.com> wrote:

> I agree that this is in some sense the least surprising. But it is so
> unpleasant that I think we should instead opt for the additional surprise
> of #3 -- that a direct sloppy eval is block-like, even though there aren't
> any curlies.
>
>
> On Fri, Feb 14, 2014 at 8:03 AM, Jeremy Martin <jmar...@gmail.com> wrote:
>
>> I rather hate to say it, but I would've actually expected:
>>
>> 4) Given that the eval'd string doesn't create anything typically
>> considered a "block", the let binding would survive past the completion of
>> the eval in non-strict mode:
>>
>>     (function() {
>>           eval("
>>               var answer=42;
>>               let localToEval = true;
>>            ");
>>           console.log(answer);  // 42
>>           console.log(localToEval);  // true
>>     )();
>>
>>      (function() {
>>           "use strict";
>>           eval("
>>                var answer=42;
>>               let localToEval = true;
>>            ");
>>           console.log(answer);  // ReferenceError: answer is not defined
>>           console.log(localToEval);  // ReferenceError: localToEval is
>> not defined
>>     )();
>>
>> I'm not necessarily arguing for that behavior, but weighing in since
>> that's the behavior I would have expected based on existing ES5
>> strict/non-strict/eval and ES6 let semantics...
>>
>>
>> On Fri, Feb 14, 2014 at 10:40 AM, Allen Wirfs-Brock <
>> al...@wirfs-brock.com> wrote:
>>
>>>
>>> On Feb 14, 2014, at 5:49 AM, André Bargull wrote:
>>>
>>>  How about this?
>>>
>>> let x= 0;
>>> if (1) eval("let x= 42; alert(x);"); //Is this in its own block?
>>> alert(x);
>>>
>>>
>>> `eval()` hasn't yet been updated to work with the new lexical
>>> declaration forms, but I hope the example from above will be evaluated in a
>>> new block. See https://bugs.ecmascript.org/show_bug.cgi?id=1788 for a
>>> related bug report.
>>>
>>>
>>> Goood point and this is something I need to specify in the next couple
>>> weeks so let's look at the alternatives.
>>>
>>> First a quick refresher on ES5 era eval.
>>>
>>> In ES5, the binding behavior of direct eval differs between strict and
>>> non-strict modes.
>>>
>>> In strict mode, each eval instantiates all declarations in a new
>>> environment that is immediately nested within the current
>>> LexicalEnvironment. The scoping behavior is essentially the same as if the
>>> eval code was the body of an iife that occurred at the same place as the
>>> eval call.  Bindings introduced by the eval code disappear after completion
>>> of the eval.
>>>
>>> In non-strict mode, each eval instantiates all declarations in the
>>> current VariableEnvironment; that is the most immediately enclosing
>>> function or global environment.  Bindings introduced by the eval code
>>> remain accessible from that VariableEnvironment after completion of the
>>> eval.
>>>
>>> For example:
>>> (function() {
>>>       "use strict";
>>>       eval("var answer=42");
>>>       console.log(answer);  // ReferenceError: answer is not defined
>>> })();
>>>
>>> (function() {
>>>       eval("var answer=42");
>>>       console.log(answer);  // 42
>>> })();
>>>
>>> For ES6, it makes sense for strict mode evals to behave in this exact
>>> same way. Each eval takes place in its own environment and no bindings
>>> survive the completion of the eval.
>>>
>>> For ES6, non-strict evals of code containing only var or function
>>> declarations must  have exactly the ES5 behavior  in order to maintain
>>> compatibility.  But what about eval code that contains new declaration
>>> forms (let/const/class) exclusively or in combination with var/function
>>> declarations? Three possibilities come to mind:
>>>
>>> 1) Extend the ES5 semantics to include the new declaration forms.  For
>>> example:
>>>
>>> (function() {
>>>       eval("let answer=42");
>>>       console.log(answer);  // 42
>>> })();
>>>
>>> 2) Use the strict mode binding semantics  if the eval code directly
>>> contains any of the new declaration forms:
>>>
>>> (function() {
>>>       eval("
>>>           var answer=42;
>>>           let forceSeprateEnvironment = true;
>>>        ");
>>>       console.log(answer);  // ReferenceError: answer is not defined
>>> })();
>>>
>>> 3) Combination.  use ES5 non-strict binding semantics for var/function
>>> declarations but place let/const/class bindings into a per eval environment:
>>>
>>> (function() {
>>>       eval("
>>>           var answer=42;
>>>           let localToEval = true;
>>>        ");
>>>       console.log(answer);  // 42
>>>       console.log(localToEval);  // ReferenceError: localToEval is not
>>> defined
>>> )();
>>>
>>>
>>> It would certainly be possible to specify #1, but I don't like it. Other
>>> than for the global environment it would be cleaner if the new block
>>> scope-able declarations  were never dynamically added to the environment.
>>>
>>> I think either #2 or #3 is plausible.  #2 is a simpler story but
>>> introduces a refactoring hazard. If you have some existing eval code that
>>>  defines some "global" functions or variables, then simply adding a
>>> let/const/class declaration to the eval code ruins those global
>>> declarations.
>>>
>>> I prefer the simplicity of #2, but I also worry about the WTF impact it
>>> might have on evolving existing code.
>>>
>>> Can we get away with #2, or are we going to have to go with #3?  Are
>>> there other alternatives?
>>>
>>> Allen
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss@mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>>
>>
>>
>> --
>> Jeremy Martin
>> 661.312.3853
>> http://devsmash.com
>> @jmar777
>>
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>>
>
>
> --
>     Cheers,
>     --MarkM
>
> _______________________________________________
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to