Take
adder <- local({
x <- 0
function() {x <<- x+1; x}
})
or equivalently
adderGen <- function(){
x <- 0
function() {x <<- x+1; x}
}
adder<-adderGen()
Calling adder() will return 1 calling it again returns 2, and so on. But how does adder keep count of this? I can't see any variables hitting the global environment, so what is actually being used to store these? Particularly in the second case, you'd expect adder to forget that it was made inside of a function call.
Every function retains the environment in which it was defined as part of the function. If f is a function then environment(f) shows it. Normally the execution environment within adderGen would be discarded when it exited but because adderGen passes a function out whose environment is the execution environment within adderGen that environment is retained as part of the function that is passed out. We can verify that by displaying the execution environment within adderGen and then verify that it is the same as the environment of adder. The trace function will insert the print statement at the beginning of the body of adderGen and will show the execution environment each time adderGen runs. environment(adder) is the same environment.
trace(adderGen, quote(print(environment())))
## [1] "adderGen"
adder <- adderGen()
## Tracing adderGen() on entry
## <environment: 0x0000000014e77780>
environment(adder)
## <environment: 0x0000000014e77780>
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