Search code examples
rfunctional-programmingargumentslazy-evaluation

R : How evaluate formals (arguments) of function?


I really looked all over the place and haven't found an answer to my question :

The Generalized Problem :

  • How do you evaluate arguments (formals()) of a R function, without launching it ?
  • How do you evaluate a whole environment in R, despite the "Lazy evaluation" of R ?

My problem :

I want to get the computation time of the arguments of ANY function in R. For example, let's consider a function :

foo <- function(x, arg1 = 2, arg2 = arg3[1], arg3 = rnorm(10^6)) {
  rnorm(10^7) # whatever time-consuming computation here
  arg3^2
  message("Too bad you had to launch the whole function !")
}

You will note the difficulties :

  • Some arguments are required (x), and some not. [Consequence : using formals() will not return the unevaluated expression of x !]
  • Some arguments are computed in function of another, defined after it (arg2 is computed with arg3)

The desired output :

> system.time(foo(x=1))
Too bad you had to launch the whole function !
       user      system      elapsed 
      1.835       0.000       1.573 

> solution.function(foo, list(x=1))
The answer is in reality much lower ! It takes only 0.2 sec to compute the arguments !

Solution

  • Generalized solution

    Very simply, it seems that as.list(environment) actually evaluates the whole environment and returns a list !

    My final solution

    Thanks to the help of Martin Morgan, I came up with that solution, very simple, and which deals with all the constraints of the problem :

    foo2 <- foo #Just copy/paste the function, before modifying it
    body(foo2) <- quote(as.list(environment())
    

    foo2(x=2) will return all the arguments of the function (evaluated), the required ones (x) as well as the default ones (arg1, arg2, arg3)

    You can check : system.time(foo2(x=1)) will return 0.2 seconds ... only rnorm(10^6) is launched.