arguments.callee and strict mode
On Tue, Mar 10, 2009 at 8:52 AM, Allen Wirfs-Brock < Allen.Wirfs-Brock at microsoft.com> wrote:
In reviewing the spec. I was reminded that arguments.callee is disabled within strict mode functions. Do you recall why you wanted to do this, other than general dislike of arguments.
POLA. A frequent and sensible pattern of use for "arguments" is to pass it along to someone else to give them access to your arguments list. In typical usage, it is not usually intended or desired to thereby give them access to the function itself, not to give them the ability to alter your parameter variables (hence the lack of joining).
It occurs to me, that using arguments.callee is the only way to express recursion within a function created using the Function constructor and that use of the Function constructor (rather than eval) should probably be encouraged for dynamically constructing functions from source code.
Why? I was thinking exactly the opposite: That we should encourage use of
eval() rather than the Function constructor for dynamic creation of functions.
It occurs to me, that using arguments.callee is the only way
to express recursion within a function created using the Function constructor and that use of the Function constructor (rather than eval) should probably be encouraged for dynamically constructing functions from source code.
It is not the only way. You can write an annonymous function that returns a named, recursive function. So arguments.callee is not required for that unlikely case.
Good point about, POLA. Of course, arguments.callee is writable (and deletable) so it could be removed or modified before passing it on.
POLA is also the reason for preferring use of the Function constructor over eval. The function constructor is essentially a constrained eval that carries less authority. In particular, in non-strict mode eval can create bindings in the Declaration Environment of its caller (or the Global Environment) and in either mode it can modify any in scope bindings. More generally, eval can execute arbitrary code and have arbitrary side-effects. None of that applies to calling the Function constructor. Those seem like really good reasons to encourage use of the Function constructor instead of eval, where possible.
Allen
From: Mark S. Miller [mailto:erights at google.com] Sent: Tuesday, March 10, 2009 9:03 AM To: Allen Wirfs-Brock Cc: Douglas Crockford; David-Sarah Hopwood; es-discuss at mozilla.org Subject: Re: arguments.callee and strict mode
On Tue, Mar 10, 2009 at 8:52 AM, Allen Wirfs-Brock <Allen.Wirfs-Brock at microsoft.com<mailto:Allen.Wirfs-Brock at microsoft.com>> wrote:
In reviewing the spec. I was reminded that arguments.callee is disabled within strict mode functions. Do you recall why you wanted to do this, other than general dislike of arguments. POLA. A frequent and sensible pattern of use for "arguments" is to pass it along to someone else to give them access to your arguments list. In typical usage, it is not usually intended or desired to thereby give them access to the function itself, not to give them the ability to alter your parameter variables (hence the lack of joining).
It occurs to me, that using arguments.callee is the only way to express recursion within a function created using the Function constructor and that use of the Function constructor (rather than eval) should probably be encouraged for dynamically constructing functions from source code. Why? I was thinking exactly the opposite: That we should encourage use of eval() rather than the Function constructor for dynamic creation of functions.
-----Original Message----- From: Douglas Crockford [mailto:douglas at crockford.com] It is not the only way. You can write an annonymous function that returns a named, recursive function. So arguments.callee is not required for that unlikely case.
Not exactly equivalent if you are using the function constructor. Assuming that the outer anonymous function is the one that is defined using the function constructor, you would have to explicitly invoke the result of the constructor to obtain an instance of the inner named function.
-----Original Message----- From: Douglas Crockford [mailto:douglas at crockford.com] It is not the only way. You can write an annonymous function that returns a named, recursive function. So arguments.callee is not required for that unlikely case.
Not exactly equivalent if you are using the function constructor. Assuming that the outer anonymous function is the one that is defined using the function constructor, you would have to explicitly invoke the result of the constructor to obtain an instance of the inner named function.
That's good enough. It doesn't need to be exactly equivalent.
On Mar 10, 2009, at 9:02 AM, Mark S. Miller wrote:
On Tue, Mar 10, 2009 at 8:52 AM, Allen Wirfs-Brock <Allen.Wirfs-Brock at microsoft.com
wrote: In reviewing the spec. I was reminded that arguments.callee is
disabled within strict mode functions. Do you recall why you wanted
to do this, other than general dislike of arguments.POLA. A frequent and sensible pattern of use for "arguments" is to
pass it along to someone else to give them access to your arguments
list. In typical usage, it is not usually intended or desired to
thereby give them access to the function itself, not to give them
the ability to alter your parameter variables (hence the lack of
joining).
The point about joining is good, but not relevant to callee. If f
calls g(arguments) and g takes formal parameter a, g cannot abuse
a.callee to alias f's active variables.
Before giving callee the boot, has anyone interacted with Ajax library
authors? Here (excluding lines longer than 256) are uses of callee in
Dojo, Ext, JQuery, MochiKit, and Prototype:
It occurs to me, that using arguments.callee is the only way to
express recursion within a function created using the Function
constructor and that use of the Function constructor (rather than
eval) should probably be encouraged for dynamically constructing
functions from source code.Why? I was thinking exactly the opposite: That we should encourage
use of eval() rather than the Function constructor for dynamic
creation of functions.
Whatever encouragement the committee gives, with words or strict mode
sticks, is not likely to have much effect on the bulk of Web code.
Strict mode sticks may have an effect over time, but carrots work
better.
The Function constructor is used far less than eval("function f()
{...}") or eval("var f = function(){...}") or even (this works only in
some implementations and is not legal syntax in ES3) eval("function ()
{...}"). When all you have is the eval hammer, everything looks like
your thumb.
Also, the Function constructor does not provide for a name (wherefore
Maciej's Function.create). And it scopes the created function to the
global object. There are reasonable use-cases for generated functions
in local scopes.
On Mar 10, 2009, at 18:26 , Brendan Eich wrote:
Before giving callee the boot, has anyone interacted with Ajax
library authors? Here (excluding lines longer than 256) are uses of
callee in Dojo, Ext, JQuery, MochiKit, and Prototype:
We've completely removed uses of arguments callee from the upcoming
release of Prototype, favoring named functions instead.
Best,
Tobie
On Mar 10, 2009, at 11:08 AM, Tobie Langel wrote:
On Mar 10, 2009, at 18:26 , Brendan Eich wrote:
Before giving callee the boot, has anyone interacted with Ajax
library authors? Here (excluding lines longer than 256) are uses of
callee in Dojo, Ext, JQuery, MochiKit, and Prototype:We've completely removed uses of arguments callee from the upcoming
release of Prototype, favoring named functions instead.
Yes, thanks -- I remember you pointed this out previously.
My find | xargs grep
hit many more callee uses in the other
libraries whose source I track.
Named function expressions and definitions are better, no question
(now that ES3.1 adopts the de-facto fix pioneered by Opera of not
binding a named function expression's name in an Object instance
created as if by "new Object"). I pointed to the numerous uses of
callee to ask whether other Ajax library authors are on board. Many
read this list.
FWIW, replacing arguments.callee with named function to make jQuery
cajole was very straightforward.
On Tue, Mar 10, 2009 at 11:11, Brendan Eich <brendan at mozilla.com> wrote:
Named function expressions and definitions are better, no question (now that ES3.1 adopts the de-facto fix pioneered by Opera of not binding a named function expression's name in an Object instance created as if by "new Object"). I pointed to the numerous uses of callee to ask whether other Ajax library authors are on board. Many read this list.
We use arguments.callee.caller in a few places to get a call stack and we rely on this feature to be able to analyze errors in production.
Spidermonkey has a stack property on the error object so we are ok in Firefox. Until all js engines have this (or some equivalent feature) I don't think we can stop using arguments.callee :'(
Didn't we already cover this? I feel like we are going around in circles.
On 11/03/2009, at 1:40, Erik Arvidsson wrote:
We use arguments.callee.caller in a few places to get a call stack and we rely on this feature to be able to analyze errors in production.
Spidermonkey has a stack property on the error object so we are ok in Firefox. Until all js engines have this (or some equivalent feature) I don't think we can stop using arguments.callee :'(
Didn't we already cover this? I feel like we are going around in
circles.
On Mar 10, 2009, at 5:40 PM, Erik Arvidsson wrote:
We use arguments.callee.caller in a few places to get a call stack and we rely on this feature to be able to analyze errors in production.
Spidermonkey has a stack property on the error object so we are ok in Firefox. Until all js engines have this (or some equivalent feature) I don't think we can stop using arguments.callee :'(
Didn't we already cover this? I feel like we are going around in
circles.
esdiscuss/2008-September/007475
Life is a karmic wheel, you can only hope to go up instead of down on
the next half-cycle.
Seriously, you're not going to get joy in ES3.1 strict mode on
arguments.callee or the caller property of Function objects, which
isn't even in ES3. Stack backtracing in some form is on the Harmony
agenda. We should try to hash out the requirements.
esdiscuss/2008-March/005776, esdiscuss/2008-September/007497, proposals:stack_inspection
In reviewing the spec. I was reminded that arguments.callee is disabled within strict mode functions. Do you recall why you wanted to do this, other than general dislike of arguments. It occurs to me, that using arguments.callee is the only way to express recursion within a function created using the Function constructor and that use of the Function constructor (rather than eval) should probably be encouraged for dynamically constructing functions from source code.