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