In what ways does the following "eval" regularity break?

Maciej Stachowiak mjs at apple.com
Wed Oct 29 23:46:44 PDT 2008


On Oct 29, 2008, at 11:23 PM, Mark S. Miller wrote:

> The intent of ES3's eval operator is clearly that it at least
> approximate the following result:
>
> For certain triples of source code text:
>    <some code a> <some code b> <some code c>
> is equivalent to
>    <some code a> eval("<some code b>") <some code c>
>
> By placing quotes around <some code b>, I am not suggesting literally
> surrounding it with quotes, but rather turning it into a string
> literal whose value is the original code string.
>
> Certainly, we understand that <some code b> must be balanced and must
> either be an expression, a statement, a block, or a function body.
>
> Even with these restrictions, there are some cases that don't work:
>
>    function foo() {eval('return 3;');}
>    foo();
>    SyntaxError on line 1: return not in function

var declaration is another thing that is different. Inside eval, var  
makes a deletable binding. break also won't work.

  - Maciej

>
>
>
> This is all intriguingly similar to our previous discussions of
> Tennent Correspondence (TC), to whit:
>
> The intent of ES3's function abstraction is clearly that it at least
> approximate lambda abstraction. If it actually provided proper lambda
> abstraction, we'd have TC (though ES is better than the vast majority
> of other languages in this regard). By understanding the ways in which
> ES3's function violates TC, we come to a better understanding of how
> to use it well, and of what hazards to watch out for. Our discussions
> on this list have really helped my understanding of function.
> Likewise, with eval, if we understand better in what ways it violates
> the regularity it approximates so well, we'll understand better the
> hazards to watch out for in the occasional uses we encounter.
>
> A case I'm particularly interested in is when <some code b> is the
> body of a function. Other than the return issue illustrated above, in
> what other ways does ES3's eval() violate this regularity? One place
> to look is the difference between the Program production + the notion
> of eval context on the one hand vs the function body production + the
> notion of function context on the other hand. In ES3.1, we allow the
> "use strict" directive only at the beginning of Program units. If one
> tried to get the effect of turning strictness on for an individual
> function body by evaling a Program string beginning with "use strict"
> that otherwise contained the function's original code, performance
> aside, and other than the above "return" issue, how else might one get
> into trouble?
>
> In a similar vein, in what ways might
>
>    new Function("<some code b>")
> differ in meaning from
>    function(){eval("<some code b>");}
>
> The obvious one: In the latter, <source code b> can refer to
> non-global variable that are in scope at eval's site. What else?

For one thing, local variables introduced by <some code b> will not be  
deletable in the first case, but will be in the latter case.

Personally I think use of the local-scope eval should be discouraged.  
We should introduce an explicit globalEval function which has eval  
function rather than eval operator semantics, i.e. evaluates at global  
scope. In my experience, programs using eval rarely truly want local  
eval, and so they are doing something that defeats lexecial analysis  
for no reason. I think we should even consider banning local eval from  
strict mode.

Regards,
Maciej



More information about the Es-discuss mailing list