Thomas Petzoldt
2008-Jan-21 13:30 UTC
[Rd] experiments with slot functions and possible problems NOTE
Hello, first of all, thanks to LT for \pkg{codeutils}. I agree that it is indeed very useful to identify errors and also to encourage re-thinking past solutions. My problem: I want to compare different sets of related sub-functions which should be used alternatively by the same top-level function. Sets of related functions should be bound together (as lists) and the workspace should be as clean as possible. Finally, these functions are to be called by top-level functions that work with such sets. What's the best way to do this? - clutter the workspace with lots of functions? OR: - ignore "notes about possible problems" OR: - a third way? Thanks in advance Thomas P. An example: ##============================================================## 1) One possible "set of functions" flistA <- list( foo = function() { 1:10 }, bar = function() { log(foo()) } ) ## .. we may also have alternative sets, ## e.g. flistB, flistC, ... etc ## 2) Now we try to construct closures ## 2a) non-nested makefun1 <- function(flist) { with(flist, function() foo() ) } ## 2b) nested call makefun2 <- function(flist) { with(flist, function() bar() ) } ## 2c) or use an alternative way with a special function ## addtoenv, suggested by Gabor Grothendieck some times ago: addtoenv <- function(L, p = parent.frame()) { for(nm in names(L)) { assign(nm, L[[nm]], p) environment(p[[nm]]) <- p } L } makefun3 <- function(flist) { addtoenv(flist) function() bar() } ## 3) now we create the "top-level" functions ## with one particular "set of functions" m1 <- makefun1(flistA) m2 <- makefun2(flistA) m3 <- makefun3(flistA) m1() ## this was no problem, trivial m2() # Error in bar() : could not find function "foo" m3() # works, but even in that case we get problems # if we do this in a package: # * checking R code for possible problems ... NOTE # bar: no visible global function definition for 'foo' ## tested with R version 2.6.1 and ## R 2.7.0 Under development, svn rev. 44061 -- Thomas Petzoldt Technische Universitaet Dresden Institut fuer Hydrobiologie 01062 Dresden GERMANY http://tu-dresden.de/Members/thomas.petzoldt
Duncan Murdoch
2008-Jan-21 13:46 UTC
[Rd] experiments with slot functions and possible problems NOTE
On 1/21/2008 8:30 AM, Thomas Petzoldt wrote:> Hello, > > first of all, thanks to LT for \pkg{codeutils}. I agree that it is > indeed very useful to identify errors and also to encourage re-thinking > past solutions. My problem: > > I want to compare different sets of related sub-functions which should > be used alternatively by the same top-level function. Sets of related > functions should be bound together (as lists) and the workspace should > be as clean as possible. > > Finally, these functions are to be called by top-level functions that > work with such sets. > > What's the best way to do this? > > - clutter the workspace with lots of functions? > OR: > - ignore "notes about possible problems" > OR: > - a third way? > > Thanks in advance > > Thomas P. > > > > An example: > > ##============================================================> ## 1) One possible "set of functions" > flistA <- list( > foo = function() { > 1:10 > }, > bar = function() { > log(foo()) > } > ) > > ## .. we may also have alternative sets, > ## e.g. flistB, flistC, ... etc > > ## 2) Now we try to construct closures > > ## 2a) non-nested > makefun1 <- function(flist) { > with(flist, > function() foo() > ) > } > > ## 2b) nested call > makefun2 <- function(flist) { > with(flist, > function() bar() > ) > } > ## 2c) or use an alternative way with a special function > ## addtoenv, suggested by Gabor Grothendieck some times ago: > addtoenv <- function(L, p = parent.frame()) { > for(nm in names(L)) { > assign(nm, L[[nm]], p) > environment(p[[nm]]) <- p > } > L > } > > makefun3 <- function(flist) { > addtoenv(flist) > function() bar() > } > > ## 3) now we create the "top-level" functions > ## with one particular "set of functions" > m1 <- makefun1(flistA) > m2 <- makefun2(flistA) > m3 <- makefun3(flistA) > > m1() > ## this was no problem, trivial > > m2() > # Error in bar() : could not find function "foo"That's because the environment of bar was the evaluation frame in effect at the time it was created, and foo wasn't in that. bar looks in its environment for non-local bindings. Gabor's function edits the environment.> > m3() > # works, but even in that case we get problems > # if we do this in a package: > > # * checking R code for possible problems ... NOTE > # bar: no visible global function definition for 'foo'This is a spurious error: codetools can't follow the strange stuff you're doing. I'd say the best approach would be to use lots of little functions, and a namespace to hide them. Then codetools will be happy. For example, Afoo <- function() { 1:10 } Abar <-function() { log(Afoo()) } fListA <- list(foo = Afoo, bar = Abar) This won't allow global references to foo or bar to escape the watchful eye of codetools; if you want those, you'd do something like foo <- function() stop("foo not initialized") bar <- function() stop("bar not initialized") and later have foo <- makefun1(fListA) bar <- makefun2(fListA) Duncan Murdoch
Gabor Grothendieck
2008-Jan-21 16:49 UTC
[Rd] experiments with slot functions and possible problems NOTE
If the intention is to place fList's contents in the global environment then you need to specify that in addtoenv or else it assumes the parent environment.> flistA <- list(foo = function () 1:10, bar = function() log(foo())) > makefun <- function(fList) addtoenv(fList, .GlobalEnv) > makefun(flistA)$foo function() { 1:10 } $bar function() { log(foo()) }> foo()[1] 1 2 3 4 5 6 7 8 9 10> bar()[1] 0.0000000 0.6931472 1.0986123 1.3862944 1.6094379 1.7917595 1.9459101 [8] 2.0794415 2.1972246 2.3025851 Note that this takes advantage of the fact that in your example flistA was defined in the global environment in the first place. Had that not been the case we would have had to reset the environment of bar so that it could find foo. By the way. What about just attach(flistA) ? On Jan 21, 2008 8:30 AM, Thomas Petzoldt <Thomas.Petzoldt at tu-dresden.de> wrote:> Hello, > > first of all, thanks to LT for \pkg{codeutils}. I agree that it is > indeed very useful to identify errors and also to encourage re-thinking > past solutions. My problem: > > I want to compare different sets of related sub-functions which should > be used alternatively by the same top-level function. Sets of related > functions should be bound together (as lists) and the workspace should > be as clean as possible. > > Finally, these functions are to be called by top-level functions that > work with such sets. > > What's the best way to do this? > > - clutter the workspace with lots of functions? > OR: > - ignore "notes about possible problems" > OR: > - a third way? > > Thanks in advance > > Thomas P. > > > > An example: > > ##============================================================> ## 1) One possible "set of functions" > flistA <- list( > foo = function() { > 1:10 > }, > bar = function() { > log(foo()) > } > ) > > ## .. we may also have alternative sets, > ## e.g. flistB, flistC, ... etc > > ## 2) Now we try to construct closures > > ## 2a) non-nested > makefun1 <- function(flist) { > with(flist, > function() foo() > ) > } > > ## 2b) nested call > makefun2 <- function(flist) { > with(flist, > function() bar() > ) > } > > ## 2c) or use an alternative way with a special function > ## addtoenv, suggested by Gabor Grothendieck some times ago: > addtoenv <- function(L, p = parent.frame()) { > for(nm in names(L)) { > assign(nm, L[[nm]], p) > environment(p[[nm]]) <- p > } > L > } > > makefun3 <- function(flist) { > addtoenv(flist) > function() bar() > } > > ## 3) now we create the "top-level" functions > ## with one particular "set of functions" > m1 <- makefun1(flistA) > m2 <- makefun2(flistA) > m3 <- makefun3(flistA) > > m1() > ## this was no problem, trivial > > m2() > # Error in bar() : could not find function "foo" > > m3() > # works, but even in that case we get problems > # if we do this in a package: > > # * checking R code for possible problems ... NOTE > # bar: no visible global function definition for 'foo' > > ## tested with R version 2.6.1 and > ## R 2.7.0 Under development, svn rev. 44061 > > > > > > -- > Thomas Petzoldt > Technische Universitaet Dresden > Institut fuer Hydrobiologie > 01062 Dresden > GERMANY > > http://tu-dresden.de/Members/thomas.petzoldt > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >
Reasonably Related Threads
- Notes on R for psychology experiments and questionnaires
- factorial experiments and repeated measures
- R code to reproduce solutions to example problems in Mathews, Design of Experiments with MINITAB
- range coding experiments?
- Help needed to analyse a factorial microarray experiments! Newbie Question