On 23/01/2019 4:53 a.m., Ivan Krylov wrote:
Hi!

I needed to generalize a loss function being optimized inside another
function, so I made it a function argument with a default value. It
worked without problems, but later I noticed that the inner function,
despite being defined in the function arguments, somehow closes over a
variable belonging to the outer function, which is defined later.

Example:

outside <- function(inside = function() print(secret)) {
        secret <- 'secret'
        inside()
}
outside()

I'm used to languages that have both lambdas and variable declaration
(like perl5 -Mstrict or C++11), so I was a bit surprised.

Defaults of variables are evaluated in the evaluation frame of the call.
So the inside() function is created in the evaluation frame, and it's environment will be that frame.

When it is called it will create a new evaluation frame (empty in your example), with a parent being its environment, i.e. the evaluation frame from when it was created, so it will be able to see your secret variable.

If it made an assignment to secret using standard "<-" assignment, it would create a new variable in its own evaluation frame, but if it used superassignment "<<-", it would modify the original secret variable.


Does this work because R looks up the variable by name late enough at
runtime for the `secret` variable to exist in the parent environment of
the `inside` function? Can I rely on it? Is this considered bad style?
Should I rewrite it (and how)?

I would consider it bad style if the inside() function had anything other than a trivial definition as in your example. However, in my opinion it would be fine to write it as

 outside <- function(inside = defaultInsideFn) {
    defaultInsideFn <- function() print(secret)
    secret <- 'secret'
    inside()
 }

which is essentially equivalent, other than having a shorter header on the outside() function.

Duncan Murdoch

______________________________________________
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

Reply via email to