name property for built-in functions??

Brendan Eich brendan at mozilla.com
Sun Mar 8 12:10:37 PDT 2009


On Mar 8, 2009, at 10:28 AM, Allen Wirfs-Brock wrote:

> I have another concern about the potential interactions between the  
> proposed name property and toString.  Apparently, there is a known  
> use case of eval'ing the result of toString'ing a function in order  
> to create a new function. If we assign synthetic names such as  
> "get_foo" or "set_foo" to syntactically defined getter/setter  
> functions or allow a user to associate a name with an anonymous  
> function which then appears in the toString representation will mean  
> that eval will parse the toString result as a FunctionDeclaration  
> rather than a FunctionExpression.

But eval requires its first argument parse as a Program, and Programs  
cannot consist entirely of, or begin with, an anonymous function  
expression.

IOW, if someone is editing function source via toString/replace/eval,  
they are not doing it portably per ES3 if the function originated as  
an anonymous function expression.

In the case of an object literal, e.g.

js> var o = { get foo() {return 42}, set foo(x)  
{print(arguments.callee)} };
js> uneval(o)
({get foo () {return 42;}, set foo (x) {print(arguments.callee);}})
js> o.foo
42
js> o.foo = 43
function (x) {
     print(arguments.callee);
}
43

there is no standard "uneval" (SpiderMonkey has one) by which you  
could hope to recover the getter and setter.

You could write such an uneval using 3.1's reflective meta-programming  
API. Say you did: then there would be no way to give a property name  
*and* a (different, assigned post-creation per the recent discussion)  
intrinsic name to an initially-anonymous getter or setter function.  
SpiderMonkey again:

js> var o = { get foo bar() {return 42}, set foo bar(x)  
{print(arguments.callee)} };
js> uneval(o)
({get foo bar() {return 42;}, set foo bar(x)  
{print(arguments.callee);}})
js> o.foo
42
js> o.foo = 43
function bar(x) {
     print(arguments.callee);
}
43

Now you are quite right that the print(arguments.callee) in the setter  
for property id foo (but with intrinsic name bar) has output a string  
that is a function definition, if parsed as a whole program. But in  
the context of o -- as the result of uneval(o) -- there is no problem,  
provided you accept the (unusual but consistent) SpiderMonkey  
extension which allows two names after the get or set.

Function context always matters, since anonymous functions are illegal  
at top level of a program or function body, and named function  
expressions moved to top level become function definitions.


> For non-strict evals, that means that the synthetic name will get  
> added to the Declaration Environment of the eval. Note that for  
> indirect evals, the Declaration Environment is now the Global  
> Environment but even for nested eval this possibility seems like a  
> hazard that that most uses are not dealing with.

True, but again it seems your hypothesis starts with an anonymous  
function being decorated with a name property, but eval of toString of  
an anonymous function (without the name decoration, or run in an ES3  
implementation) produces an anonymous function which standard eval  
will reject.


> Of course, this issue already exists in ES3 for syntactically named  
> functions and functions that are internally assigned the name  
> "anonymous" so maybe these additions aren't actually making things  
> much worse.

The "anonymous" botch is peculiar to the Function constructor. I like  
Maciej's Function.create proposal, and it helps us avoid making more  
bad law on the old "anonymous" hard case.


> However, this concern along with Maciej's latest suggestions about  
> Function.create pushes me further in the direction that we should  
> hold off on adding a function name property in ES3.1.

Still with you on holding off for 3.1, but we are clearly making  
progress via es-discuss toward a Harmonious proposal.


>  We still might want to consider enhancing the specification of  
> toString to explicitly address the naming of functions created other  
> than by a FunctionDeclaration/FunctionExpression. However, since  
> some of the same issues arise there I'm inclined to leave it as  
> implementation defined for ES3.1.

Agreed.

/be

>
>
> Allen
>
>
>
>



More information about the Es-discuss mailing list