Ye olde arguments argument (was: Topic list - pending changes and issues for the ES3.1 spec)

Jon Zeppieri jaz at
Thu Sep 11 18:03:40 PDT 2008

On Thu, Sep 11, 2008 at 7:09 PM, Peter Michaux <petermichaux at> wrote:
> On Thu, Sep 11, 2008 at 3:40 PM, Jon Zeppieri <jaz at> wrote:
>> On Thu, Sep 11, 2008 at 5:59 PM, Peter Michaux <petermichaux at> wrote:
>>> On Thu, Sep 11, 2008 at 12:11 PM, Jon Zeppieri <jaz at> wrote:
>>> [snip]
>>>> I imagine the appeal of arguments.callee comes from the fact that it
>>>> allows programmers to rename functions without having to change
>>>> recursive calls within the body of the function.
>>> It makes recursive calls inside anonymous functions possible.
>> No.  See "fixpoint combinator."
> I was thinking about that in particular and thinking that
> arguments.callee makes a complex concept like fixpoint combinator
> something that is very easy to understand and use.

I don't see how.
At best you could say that arguments.callee obviates the need to
understand or use a fixpoint combinator.  But the same can be said of
plain old variable definitions in ES.

>> But that's a somewhat flippant response.  More to the point: if you
>> want recursion, one way or another, you need to be able to refer to
>> the function in question.  'arguments.callee' allows you to refer to
>> it but violates the Tennent Correspondence.
> Isn't Tennent Correspondence completely shot anyway in ECMAScript?

[MarkM already responded to this.]

>> So, given that you can
>> either refer to the function this way:
>> var foo = bar() { ... bar ...}
>>   or this way:
>> function bar() { ... arguments.callee ... }
>> ... it's not clear to me what advantage the latter has over the former
>> (IE bugs aside, that is).  Anonymity itself doesn't seem to be a
>> virtue.
> There is a large advantage in keeping code bulk down. There have been
> times that I've marveled at the utility of arguments.callee. Sometimes
> the variable that refers to a function value will be reassigned,
> arguments.callee just keeps working but your first example above
> breaks.

My example above is incorrect (sorry).  It should be:

var foo = function bar() { ... bar() ... }
function foo() { ... arguments.callee ... }

In ES3 (though, apparently not in JScript 5.8, as liorean pointed
out), bar is scoped to the function expression, not to the enclosing
scope.  If you do the following:

   var foo = function bar() { ... bar() ... }
   bar = 5;

... the assignment to bar does not break the function.


More information about the Es-discuss mailing list