Finally, I understood my own answer
There are two reasons why this happens: the for loop does not have its own environment, and wrapper lazily evaluates its parameter f .
For the first reason: for loop uses the global environment
For the last reason: changing wrapper to function(f){force(f); function()f()} function(f){force(f); function()f()} leads to my expected result in the question.
Detailed explanation:
The cycle in question is interpreted in
for(n in names(fs)){ tmp <- fs[[n]] ws[[n]] <- wrapper(tmp) }
Since wrapper lazily evaluates the parameter f , it stores f in its runtime, but does not save its value. Instead, he remembers the method of estimating f when necessary. In other words, it remembers the pair (<environment: R_GlobalEnv>, "tmp") .
Checking the following code clears everything I said.
tmp <- f wf <- wrapper(tmp) tmp <- g wf() [1] "call g"
but
tmp <- f wf <- wrapper(tmp) wf() [1] "call f" tmp <- g wf() [1] "call f"
The last code printed "call f" in the second call because f is evaluated and stored in the wrapper environment, and there is no need to evaluate again (become g )
source share