I am not sure what the promises are doing in R
If one runs
a = lapply(seq_len(2), function(n) { function() {n}})
b = lapply(seq_len(2), function(n) {n})
we can see that
a[[1]]() # == 2
b[[1]] # == 1
I understand that R uses promise's object and lazily evaluates an expression in its environment, but I dont understand why the different environments created for each function would not contain their own value for n.
[[1]]
function ()
{
n
}
<environment: 0x7f9b2416ad18>
[[2]]
function ()
{
n
}
<environment: 0x7f9b2416ab20>
as.list(environment(a[[1]]))
$n
[1] 2
as.list(environment(a[[2]]))
$n
[1] 2
Is it be possible to fix the semantic through the lapply function somehow ?
lapply
function (X, FUN, ...)
{
FUN <- match.fun(FUN)
if (!is.vector(X) || is.object(X))
X <- as.list(X)
.Internal(lapply(X, FUN))
}
<bytecode: 0x7f9b25150f18>
<environment: namespace:base>
PS : refocused question
Edit : concretely, is it possible to write a lapply2 function that generically "forces" the argument to have uniform behaviour as in :
pl <- lapply (1:3, function(y) { force(y); function(x) pow(x,y) } )
pl <- lapply2(1:3, function(y) { function(x) pow(x,y) } )
I find it easier to understand in this form:
f=function(n) {function() {n}}
x=1
a=f(x)
x=2
a()
[1] 2
The key part of the documentation is
When a function is called the arguments are matched and then each of the formal arguments is bound to a promise. The expression that was given for that formal argument and a pointer to the environment the function was called from are stored in the promise.
After the call a=f(x)
, the function argument n
is bound to a promise with the name x
and a pointer to the global environment .GlobalEnv
.
In your lapply
examples, the anonymous function function(n) { function() {n}}
is called from the global environment each time. This is why every element of the list a
gets the same value of n
: it's coming from the global environment. I don't see how it's possible to change this behaviour by rewriting lapply.
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