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





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

Reply via email to