Here is a bizarre recursive function I've written to help me understand the relationships between sys.parent() and the environment:
dive = function(level = 1, max.depth = 5)
{
m = match.call()
print(paste("sys.frame() says", format(sys.frame())))
print(paste("sys.parent() says", sys.parent()))
print(paste("sys.frame(sys.parent()) says", format(sys.frame(sys.parent()))))
m[[2]] = m[[2]]+1
if(m[[2]] > max.depth)
stop("Not actually an error -- we're just tripping out!")
eval(m)
}
Running the function gives
dive(level = 1, max.depth = 5)
[1] "sys.frame() says <environment: R_GlobalEnv>"
[1] "sys.parent() says 0"
[1] "sys.frame(sys.parent()) says <environment: R_GlobalEnv>"
[1] "sys.frame() says <environment: R_GlobalEnv>"
[1] "sys.parent() says 1"
[1] "sys.frame(sys.parent()) says <environment: 0x2831dd0>"
[1] "sys.frame() says <environment: R_GlobalEnv>"
[1] "sys.parent() says 4"
[1] "sys.frame(sys.parent()) says <environment: 0x3b1dff8>"
[1] "sys.frame() says <environment: R_GlobalEnv>"
[1] "sys.parent() says 7"
[1] "sys.frame(sys.parent()) says <environment: 0x3b31c68>"
[1] "sys.frame() says <environment: R_GlobalEnv>"
[1] "sys.parent() says 10"
[1] "sys.frame(sys.parent()) says <environment: 0x3c238c0>"
Error in dive(level = 5, max.depth = 5) :
Not actually an error -- we're just tripping out!
There is a lot going on here, but I'll keep my question simple: Why does sys.parent() increment first by 1 (from 0 to 1) then subsequently by 3 (i.e., 1, 4, 7, 10 ...)?
The parent of the global environment is the last package that you loaded. The only environment that doesn't have a parent is the empty environment. The enclosing environment of a function is the environment where it was created. It determines where a function looks for variables.
There are two ways to create a nested function in the R programming language: Calling a function within another function we created. Writing a function within another function.
The environment is a virtual space that is triggered when an interpreter of a programming language is launched. Simply, the environment is a collection of all the objects, variables, and functions.
For example, by nesting the AVERAGE and SUM function in the arguments of the IF function, the following formula sums a set of numbers (G2:G5) only if the average of another set of numbers (F2:F5) is greater than 50. Otherwise, it returns 0. The AVERAGE and SUM functions are nested within the IF function.
That's because you call dive via eval.
The example below will make clear:
> dive = function(level = 1, max.depth = 5)
+ {
+ m = match.call()
+ print(sys.calls())
+ cat("======================\n\n")
+ m[[2]] = m[[2]]+1
+ if(m[[2]] > max.depth)
+ stop("Not actually an error -- we're just tripping out!")
+ eval(m)
+ }
>
> dive(level = 1, max.depth = 3)
[[1]]
dive(level = 1, max.depth = 3)
======================
[[1]]
dive(level = 1, max.depth = 3)
[[2]]
eval(m)
[[3]]
eval(expr, envir, enclos)
[[4]]
dive(level = 2, max.depth = 3)
======================
[[1]]
dive(level = 1, max.depth = 3)
[[2]]
eval(m)
[[3]]
eval(expr, envir, enclos)
[[4]]
dive(level = 2, max.depth = 3)
[[5]]
eval(m)
[[6]]
eval(expr, envir, enclos)
[[7]]
dive(level = 3, max.depth = 3)
======================
Error in dive(level = 3, max.depth = 3) :
Not actually an error -- we're just tripping out!
Here is the modified version, which increments by one.
> dive = function(level = 1, max.depth = 5)
+ {
+ print(sys.calls())
+ cat("======================\n\n")
+ if(level+1 > max.depth)
+ stop("Not actually an error -- we're just tripping out!")
+ dive(level+1, max.depth)
+ }
>
> dive(level = 1, max.depth = 3)
[[1]]
dive(level = 1, max.depth = 3)
======================
[[1]]
dive(level = 1, max.depth = 3)
[[2]]
dive(level + 1, max.depth)
======================
[[1]]
dive(level = 1, max.depth = 3)
[[2]]
dive(level + 1, max.depth)
[[3]]
dive(level + 1, max.depth)
======================
Error in dive(level + 1, max.depth) :
Not actually an error -- we're just tripping out!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With