[R] Function in default parameter value closing over variables defined later in the enclosing function

Jan T Kim jttk|m @end|ng |rom goog|em@||@com
Wed Jan 23 18:20:49 CET 2019


Hi Duncan,

On Wed, Jan 23, 2019 at 10:02:00AM -0500, Duncan Murdoch wrote:
> On 23/01/2019 5:27 a.m., Jan T Kim wrote:
> >Hi Ivan & All,
> >
> >R's scoping system basically goes to all environments along the call
> >stack when trying to resolve an unbound variable, see the language
> >definition [1], section 4.3.4, and perhaps also 2.1.5.
> 
> You are misinterpreting that section.  It's not the call stack that is
> searched, it's the chain of environments that starts with the evaluation
> frame of the current function.  Those are very different.

yes -- I meant the environment chain but mistakenly wrote "call stack",
sorry. Thanks for pointing this out.

Best regards, Jan


> For example,
> 
> 
> g <- function() {
>   print(secret)
> }
> 
> f <- function() {
>   secret <- "secret"
>   g()
> }
> 
> would fail, because even though secret is defined in the caller of g() and
> is therefore in the call stack, that's irrelevant:  it's not in g's
> evaluation frame (which has no variables) or its parent (which is the global
> environment if those definitions were evaluated there).
> 
> Duncan Murdoch
> 
> >
> >Generally, unbound variables should be used with care. It's a bit
> >difficult to decide whether and how the code should be rewritten,
> >I'd say that depends on the underlying intentions / purposes. As it
> >is, the code could be simplified to just
> >
> >     print("secret");
> >
> >but that's probably missing the point.
> >
> >Best regards, Jan
> >
> >
> >[1] https://cran.r-project.org/doc/manuals/r-release/R-lang.html
> >
> >On Wed, Jan 23, 2019 at 12:53:01PM +0300, 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.
> >>
> >>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)?
> >>
> >>-- 
> >>Best regards,
> >>Ivan
> >>
> >>______________________________________________
> >>R-help using 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.
> >
> >______________________________________________
> >R-help using 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.
> >
> 
> ______________________________________________
> R-help using 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.



More information about the R-help mailing list