Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

promise already under evaluation: recursive default argument reference or earlier problems?

Tags:

r

Formal arguments of the form x=x cause this. Eliminating the two instances where they occur we get:

f <- function(x, T) {
   10 * sin(0.3 * x) * sin(1.3 * x^2) + 0.001 * x^3 + 0.2 * x + 80 
}

g <- function(x, T, f. = f) {  ## 1. note f.
   exp(-f.(x)/T) 
}

test<- function(g. = g, T = 1) {  ## 2. note g.
   g.(1,T) 
}

test()
## [1] 8.560335e-37

If you especify argument evaluation context, you avoid the problem of same name:

f <- function(x) {
  10 * sin(0.3 * x) * sin(1.3 * x ^ 2) + 0.001 * x ^ 3 + 0.2 * x + 80
}
g <- function(x, t=1, f=parent.frame()$f) {
  exp(-f(x) / t)
}
test <- function(g=parent.frame()$g, t=1) { 
  g(1,t)
}
test()
[1] 8.560335e-37

As already mentioned, the problem comes from having a function argument defined as itself. However, I want to add an explanation of why this is a problem because understanding that led me to an easier (for me) way to avoid the problem: just specify the argument in the call instead of the definition.

This does not work:

x = 4
my.function <- function(x = x){} 
my.function() # recursive error!

but this does work:

x = 4
my.function <- function(x){} 
my.function(x = x) # works fine!

Function arguments exist in their own local environment.

R looks for variables first in the local environment, then in the global environment. This is just like how inside a function a variable can have the same name as a variable in the global environment, and R will use the local definition.

Having function argument definitions form their own local environment is why you can have default argument values based on other argument values, like

my.function <- function(x, two.x = 2 * x){}

So this is why you cannot DEFINE a function as my.function <- function(x = x){} but you can CALL the function using my.function(x = x). When you define the function, R gets confused because it finds the argument x = as the local value of x, but when you call the function R finds x = 4 in the local environment you are calling from.

So in addition to fixing the error by changing the argument name or explicitly specifying the environment as mentioned in other answers, you can also just specify that x=x when you call the function instead of when you define it. For me, specifying that x=x in the call was the best solution, since it does not involve extra syntax or accumulating more and more variable names.


I like the G. Grothendieck answer, but I was wondering that is more simple in your case to not include function names in the parameters of functions, like this:

f <- function(x, T) {
  10 * sin(0.3 * x) * sin(1.3 * x^2) + 0.001 * x^3 + 0.2 * x + 80 
}
g <- function(x, T) {
  exp(-f(x)/T) 
}
test<- function(T = 1) {
  g(1,T)
}
test()
## [1] 8.560335e-37