Yes, Duncan. My statement was wrong. I should have said that it's the environment/evaluation frame of f = g(). Thank you for the correction. Still, I hope my example was helpful.
Cheers, Bert Bert Gunter "The trouble with having an open mind is that people keep coming along and sticking things into it." -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) On Mon, Mar 21, 2016 at 8:30 AM, Duncan Murdoch <murdoch.dun...@gmail.com> wrote: > On 21/03/2016 11:19 AM, Bert Gunter wrote: >> >> Martin, All: >> >> A very nice point! Perhaps the following may help to illustrate it. >> >> g <- function(){ >> x <- NULL >> function(y){cat("result is ",x," \n"); x <<- y} >> } >> >> >> > f <- g() >> >> > rm(g) # g is deleted but its environment remains as the environment of f > > > That's not quite the jargon we use. The environment of g would probably be > the global environment. The thing that gets left behind is the evaluation > frame (or environment) of the call g(). Its parent environment is the > environment of g. > > Duncan Murdoch >> >> >> > f(1) >> result is >> >> > f(3) >> result is 1 >> >> > f(5) >> result is 3 >> >> >> Best, >> Bert >> >> >> >> >> >> Bert Gunter >> >> "The trouble with having an open mind is that people keep coming along >> and sticking things into it." >> -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) >> >> >> On Mon, Mar 21, 2016 at 2:41 AM, Martin Maechler >> <maech...@stat.math.ethz.ch> wrote: >> >>>>>> Duncan Murdoch <murdoch.dun...@gmail.com> >> >>>>>> on Sat, 19 Mar 2016 17:57:56 -0400 writes: >> > >> > > On 19/03/2016 12:45 PM, Boris Steipe wrote: >> > >> Dear all - >> > >> >> > >> I need to have a function maintain a persistent lookup table of >> > results for an expensive calculation, a named vector or hash. I know that I >> > can just keep the table in the global environment. One problem with this >> > approach is that the function should be able to delete/recalculate the >> > table >> > and I don't like side-effects in the global environment. This table really >> > should be private. What I don't know is: >> > >> -A- how can I keep the table in an environment that is private to >> > the function but persistent for the session? >> > >> -B- how can I store and reload such table? >> > >> -C- most importantly: is that the right strategy to initialize >> > and maintain state in a function in the first place? >> > >> >> > >> >> > >> For illustration ... >> > >> >> > >> ----------------------------------- >> > >> >> > >> myDist <- function(a, b) { >> > >> # retrieve or calculate distances >> > >> if (!exists("Vals")) { >> > >> Vals <<- numeric() # the lookup table for distance values >> > >> # here, created in the global env. >> > >> } >> > >> key <- sprintf("X%d.%d", a, b) >> > >> thisDist <- Vals[key] >> > >> if (is.na(thisDist)) { # Hasn't been calculated yet ... >> > >> cat("Calculating ... ") >> > >> thisDist <- sqrt(a^2 + b^2) # calculate with some expensive >> > function ... >> > >> Vals[key] <<- thisDist # store in global table >> > >> } >> > >> return(thisDist) >> > >> } >> > >> >> > >> >> > >> # run this >> > >> set.seed(112358) >> > >> >> > >> for (i in 1:10) { >> > >> x <- sample(1:3, 2) >> > >> print(sprintf("d(%d, %d) = %f", x[1], x[2], myDist(x[1], x[2]))) >> > >> } >> > >> > >> > > Use local() to create a persistent environment for the function. >> > For >> > > example: >> > >> > > f <- local({ >> > > x <- NULL >> > > function(y) { >> > > cat("last x was ", x, "\n") >> > > x <<- y >> > > } >> > > }) >> > >> > > Then: >> > >> > >> f(3) >> > > last x was >> > >> f(4) >> > > last x was 3 >> > >> f(12) >> > > last x was 4 >> > >> > > Duncan Murdoch >> > >> > Yes, indeed. >> > Or use another function {than 'local()'} which returns a >> > function: The functions approxfun(), splinefun() and ecdf() >> > are "base R" functions which return functions "with a >> > non-trivial environment" as I use to say. >> > >> > Note that this is *the* proper R way solving your problem. >> > >> > The fact that this works as it works is called "lexical scoping" >> > and also the reason why (((regular, i.e., non-primitive))) >> > functions in R are called closures. >> > When R was created > 20 years ago, this has been the >> > distinguishing language feature of R (in comparison to S / S-plus). >> > >> > Enjoy! - Martin >> > >> > ______________________________________________ >> > 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. > > ______________________________________________ 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.