tags:

views:

81

answers:

2

Say I have the following function:

foo <- function(x, y = min(m)) {
    m <- 1:10
    x + y
}

When I run foo(1), the returned value is 2, as expected. However, I cannot run foo(1, y = max(m)) and receive 11, since lazy evaluation only works for default arguments. How can I supply an argument but have it evaluate lazily?

A: 

My solution was to just change the default argument:

R> formals(foo)$y <- call("max", as.name("m"))
R> foo(1)
[1] 11
brentonk
+3  A: 

The simple answer is that you can't and shouldn't try to. That breaks scope and could wreak havoc if it were allowed. There are a few options that you can think about the problem differently.

first pass y as a function

foo<-function(x,y=min){
m<-1:10
x+y(m)
}

if a simple function does not work you can move m to an argument with a default.

foo<-function(x,y=min(m),m=1:10){
x+y(m)
}

Since this is a toy example I would assume that this would be too trivial. If you insist on breaking scope then you can pass it as an expression that is evaluated explicitly.

foo<-function(x,y=expression(min(m))){
m<-1:10
x+eval(y)
}

Then there is the option of returning a function from another function. And that might work for you as well, depending on your purpose.

bar<-function(f)function(x,y=f(m)){
m<-1:10
x+y
}
foo.min<-bar(min)
foo.min(1)  #2
foo.max<-bar(max)
foo.max(1)  #10

But now we are starting to get into the ridiculous.

Andrew Redd