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