Ivan Krylov
2019-Jan-24 14:39 UTC
[R] Function in default parameter value closing over variables defined later in the enclosing function
Dear Jan & Duncan, Thanks for your replies! On Wed, 23 Jan 2019 09:56:25 -0500 Duncan Murdoch <murdoch.duncan at gmail.com> wrote:> 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.Nice explanation about closures in R inheriting not only their explicitly captured variables, but whole environments of evaluation (not stack) frames where they have been created.> in my opinion it would be fine to write it as > > outside <- function(inside = defaultInsideFn) { > defaultInsideFn <- function() print(secret) > secret <- 'secret' > inside() > }I like this idea; I'm going to use it. -- Best regards, Ivan
Jeff Newmiller
2019-Jan-24 14:53 UTC
[R] Function in default parameter value closing over variables defined later in the enclosing function
My objection to this design pattern is that this gives the default implementation of inside an ability that cannot be altered using functions provided by the caller. You might think this is what you want now but it has the potential to render the code unreusable in the future, which renders the whole idea of making inside an argument to outside pointless. It would be better to also make secret an argument to outside instead of a local variable or to give up on supplying the inside function as an argument. On January 24, 2019 6:39:49 AM PST, Ivan Krylov <krylov.r00t at gmail.com> wrote:>Dear Jan & Duncan, > >Thanks for your replies! > >On Wed, 23 Jan 2019 09:56:25 -0500 >Duncan Murdoch <murdoch.duncan at gmail.com> wrote: > >> 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. > >Nice explanation about closures in R inheriting not only their >explicitly captured variables, but whole environments of evaluation >(not stack) frames where they have been created. > >> in my opinion it would be fine to write it as >> >> outside <- function(inside = defaultInsideFn) { >> defaultInsideFn <- function() print(secret) >> secret <- 'secret' >> inside() >> } > >I like this idea; I'm going to use it.-- Sent from my phone. Please excuse my brevity.
Ivan Krylov
2019-Jan-26 13:39 UTC
[R] Function in default parameter value closing over variables defined later in the enclosing function
On Thu, 24 Jan 2019 06:53:20 -0800 Jeff Newmiller <jdnewmil at dcn.davis.ca.us> wrote:> It would be better to also make secret an argument to outside instead > of a local variable or to give up on supplying the inside function as > an argument.This was in a small, mostly self-contained one-off script that tested different design of experiment approaches with simulated datasets. Actually, I should move the "secret" variable to the global level, together with other global settings like the dataset size and noise level. There it's accessible to both any functions that might be interested in it and the user who might want to change it, after all. -- Best regards, Ivan