Can somebody please explain what happens when an expression is evaluated in system.time
? In particular, why are any variables that are declared in the expr
argument visible in the global environment?
Here is a pared-down version of the innards of system.time
that does nothing other than evaluating the expression that is passed to the function:
st <- function(expr){
expr
}
st(aa <- 1)
aa
[1] 1
Clearly the effect of this is that it creates the variable aa
in the global environment. This baffles me, since I thought that assigning a variable inside a function makes it local in scope.
What happens here?
It is because supplied arguments are evaluated in the evaluation frame of the calling function (as described in Section 4.3.3 of the R Language Definition document).
The expression wrapped by the user in
system.time()
is a supplied argument which gets matched positionally toexpr
. Then, whenexpr
's evaluation is forced in the body ofsystem.time
, it is evaluated in the evaluation frame of the calling function. Ifsystem.time()
was called from the.GlobalEnv
, that is where any assignments that are a part ofexpr
will take place.EDIT:
Here's an example showing that
expr
is evaluated in the global environment if it is a supplied (but not a default) argument.EDIT : as per @Tommy's comment: The evaluation actually only takes place once the argument expr is used (that's the lazy evaluation).
What is passed is a language object, not an expression. You basically nest the
<-
function (with two arguments) within the st() function call, and the result of the<-
call is passed to to st. As you can see in?assignOps
, the<-
function returns the assigned value silently. As @Josh told you already, this evaluation of the nested function takes place in the environment the function is called from.What you do, is equivalent to
To see the difference, you can do:
For the structure of the call, you can do:
I think the
expr
is evaluated before handling that to the function. POC example:So I think the function gets
expr
as onlyaa
. Another example:I might be wrong, it is rather an intuition :) But thanks, that is a good puzzle!
Update: