Skip to content

deferred call

4 messages · Whit Armstrong, Gabor Grothendieck, Bert Gunter

#
I must admit I'm a little ashamed to have been using R for so long,
and still lack a sound understanding of deferred calls, eval, deparse,
substitute, and friends.

I'm attempting to make a deferred call to a function which has default
arguments in the following way:

call.foo <- function(f) {
    x <- f()
}

x <- 1:10
f <- function(x=x) { x^2 }
call.foo(f)

However, I'm getting the error:
Error in x^2 : 'x' is missing

Is there a common R idiom for calling 'formals' on the function, and
then grabbing the named default arguments from the enclosing frame?

I naively thought that since function 'f' was defined w/ a default
argument of 'x' and x is defined in the same envir as the function
itself, that the call would succeed.

-Whit
#
On Wed, Apr 11, 2012 at 10:17 PM, Whit Armstrong
<armstrong.whit at gmail.com> wrote:
f <- function(x=x) x^2 is an endless recursion.  Try

 f <- function(x.=x) { x^2 }

(note the dot)
#
On Wed, Apr 11, 2012 at 8:12 PM, Gabor Grothendieck
<ggrothendieck at gmail.com> wrote:
To amplify just a bit on Gabor's comment, section 4.3.3 of the R
language definition explicitly states:

"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."

So foo <- function (x = x) {...}
tries to define foo with the default argument x, which is evaluated in
the ** environment of the function ** not in the caller's environment,
where it is 1:10.  So if x ever needs to be evaluated within foo
(i.e., its promise is forced), then it looks for the value of the rhs
of the x=x  assignment within foo, which is (the promise for) x,
again, within foo, which is x again,...

HTH

-- Bert

  
    
#
Bert and Gabor,

Thanks for clarifying. Much appreciated.

One more question.  Do either of you know the location of the code
that does the lookup of the default arguments?

I would like to be able to capture the implicit dependency of the
function on the default arguments.

Hence, I would write something like:

capture.dag <- function(fun) {
    ans <- list()
    args <- formals(fun)
    for(nm in names(args)) {
        ans[[ nm ]] <- lookup.the.object(args[[nm]])
    }

    ans
}

However, it seems that this logic is already implemented in the core
of R, and it would be great to re-use it.

Thanks,
Whit
On Thu, Apr 12, 2012 at 1:00 AM, Bert Gunter <gunter.berton at gene.com> wrote: