[R] "recursive default argument" error

Wacek Kusnierczyk Waclaw.Marcin.Kusnierczyk at idi.ntnu.no
Tue Nov 25 11:51:42 CET 2008

tolga.i.uzuner at jpmorgan.com wrote:
> Dear R Users,
> I have a function foo in a script with default values for some of the 
> parameters as follows:
> testparams=list(a=1,b=2,c=3)
> foo<-function(x,y,testparams=testparams)
>         x+y+testparams$a+testparams$b+testparams$c
> When I try to run foo(1,2), I get the following error:
>> testparams=list(a=1,b=2,c=3)
>> foo<-function(x,y,testparams=testparams)
> + x+y+testparams$a+testparams$b+testparams$c
>> foo(1,2)
> Error in foo(1, 2) : 
>   promise already under evaluation: recursive default argument reference 
> or earlier problems?

sure.  from the r language manual, sec. 4.3.3:

"One of the most important things to know about the evaluation of
arguments to a function is
that supplied arguments and default arguments are treated differently.
The supplied arguments
to a function are evaluated in the evaluation frame of the calling
function. The default arguments
to a function are evaluated in the evaluation frame of the function."

the parameter testparams, when no matching argument is passed, is given
the default value which is the value of the variable testparams
looked-up *not* in the environment where foo is defined, and *not* in
the environment where foo is called, but rather in the local environment
created when the function is called and where parameters are mapped to
values -- and in this environment, testparams is a parameter, which is
already being under evaluation, hence the recursive lookup error.

in some programming languages, testparams (the default value) would come
from the definition-time environment, so you'd not have problems; in
others, it's more like in r:

python> x = 1; def foo(x, y=x): return y; foo(2) # 1
ruby> x = 1; def foo(x, y=x); y; end; foo(2) # 2

you just have to get used to it.

> I can obviously rename testparams but I would still like to understand why 
> this breaks. I would have thought the right hand side of 
> "testparams=testparams" would have been evaluated in the namespace outside 
> the script and not the function. How can I force it to be evaluated in the 
> namespace outside the function ?

something like this ugly hack seems to solve the problem:

foo = function(testparams = get("testparams", envir=environment(foo))


More information about the R-help mailing list