Lazy assessment of the arguments

Let's say I have the following function:

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

When I ran foo(1) , the return value is 2 , as expected. However, I cannot run foo(1, y = max(m)) and get 11 , because lazy evaluation only works for default arguments. How can I put an argument, but it lazily evaluates?

+7
r lazy-evaluation
source share
3 answers

The simple answer is: you cannot and should not try. This is out of scale and can be detrimental if allowed. There are several options that you can think of a problem differently.

pass y as a function first

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

If a simple function does not work, you can move m to the argument with the default value.

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

Since this is an example of a toy, I would suggest that it would be too trivial. If you insist on breaking the area, you can pass it as an expression that is explicitly evaluated.

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

Then it is possible to return a function from another function. And it may work for you, depending on your goal.

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

+6
source share

My solution was to simply change the default argument:

 R> formals(foo)$y <- call("max", as.name("m")) R> foo(1) [1] 11 
+1
source share

You can use a combination of substitute , eval .

 foo <- function(x, y = min(m)) { y <- substitute(y) m <- 1:10 x + eval(y) } foo(1) ## [1] 2 foo(1, y = max(m)) ## [1] 11 
0
source share

All Articles