From ripley at stats.ox.ac.uk  Tue Sep 12 08:42:42 2006
From: ripley at stats.ox.ac.uk (Prof Brian Ripley)
Date: Tue, 12 Sep 2006 07:42:42 +0100 (BST)
Subject: [Rd] unexpected behaviour when defining a function
In-Reply-To: <eb555e660609111626t3f03dd69q2e3ebfe845f6540c@mail.gmail.com>
References: <eb555e660609111626t3f03dd69q2e3ebfe845f6540c@mail.gmail.com>
Message-ID: <Pine.LNX.4.64.0609120725010.10962@gannet.stats.ox.ac.uk>

On Mon, 11 Sep 2006, Deepayan Sarkar wrote:

> Hi,
> 
> I know S manuals used to warn against using the same names for a
> variable and a function, but I have never seen that cause problems in
> R, so I usually don't pay much attention to it. 

But in this case you have a promise.  (BTW, it can still cause problems in 
R, hence the following NEWS item for 2.4.0:

	Lookup for S3 methods is confined to functions: previously a
	non-function 'fun.class' could have masked a function of the
	same name.
)

Note that you do have to look at an object to find out if it is a 
function, and that means forcing promises, the problem here.

> Which is why the following behaviour came as a surprise:
> 
> > bar <- function() 1
> > foo <- function(bar = bar()) {
> +     bar
> + }
> > foo(9)
> [1] 9
> > foo()
> Error in foo() : recursive default argument reference
> 
> Exactly what rule am I violating here?

That an argument default value cannot refer to the argument.

This is an argument with a default value that is relying on lazy 
evaluation. When you come to evaluate 'bar' it is a promise with value 
bar().  Evaluating that value looks up 'bar' from the evaluation frame of 
foo() and the first candidate it finds is the argument it is the process 
of evaluating, hence the message.

> The following gives a slightly different error, but I assume it has a
> similar origin:
> 
> bar <- function() 1
> foo <- function(bar) {
>     if (missing(bar)) bar <- bar()
>     bar
> }
> foo()

It says

> Error in foo() : argument "bar" is missing, with no default

and that is caused by bar <- bar():  it is looking for argument bar (to 
see if it is a function which can be called) and that argument has no 
default.  (I would have thought that one was clear enough.)

-- 
Brian D. Ripley,                  ripley at stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595




[Rd] unexpected behaviour when defining a function
Prof Brian Ripley