From murdoch at stats.uwo.ca  Mon Jan 21 18:13:39 2008
From: murdoch at stats.uwo.ca (Duncan Murdoch)
Date: Mon, 21 Jan 2008 12:13:39 -0500
Subject: [Rd] experiments with slot functions and possible problems NOTE
In-Reply-To: <4794CD50.2080604@tu-dresden.de>
References: <47949E59.9070603@tu-dresden.de>
	<4794A234.5050008@stats.uwo.ca>	<4794B321.6030907@tu-dresden.de>
	<4794B93A.6050309@stats.uwo.ca> <4794CD50.2080604@tu-dresden.de>
Message-ID: <4794D2C3.3080704@stats.uwo.ca>

On 1/21/2008 11:50 AM, Thomas Petzoldt wrote:
> Duncan Murdoch wrote:
>> On 1/21/2008 9:58 AM, Thomas Petzoldt wrote:
>>> Hello Duncan,
>>>
>>> thank you very much for your prompt reply. When I interpret your answer
>>> correctly there seems to be no alternative than either:
>>>
>>> A) using lots of (possibly private) functions in the package or,
>>> B) define dummies for all functions which are in such lists or,
>>> C) ignore the NOTE, knowing that it is spurious (BTW: there are several
>>> prominent packages on CRAN with unresolved NOTEs).
> 
> [...]
> 
>> There's another way, which is more R-like, if you really want to avoid
>> lots of private functions.  That is to create your lists via a function,
>> and define the functions in the lists locally within the creator.  That
>> is, something like this:
>>
>> MakeListA <- function() {
>>   foo <- function() {
>>       1:10
>>   }
>>   bar <-function() {
>>        log(foo())
>>   }
>>   return(list(foo = foo, bar = bar))
>> }
>>
>> fListA <- MakeListA()
>>
>> This avoids the explicit environment manipulations.  Because both foo
>> and bar are defined locally within MakeListA, they share an environment
>> there, and can see each other (and anything else you chose to define
>> locally within MakeListA.)
> 
> [...]
> 
> Cool! What about the following (AFAIK getting environments is "legal" as
> opposed to setting them):
> 
> MakeListA <- function() {
>     foo <- function() {
>       1:10
>     }
>     bar <-function() {
>       log(foo())
>     }
>     return(as.list(environment()))
> }
> 
> fListA <- MakeListA()

Yes, that's fine.  Another variation is

fListA <- local({
      foo <- function() {
        1:10
      }
      bar <-function() {
        log(foo())
      }
      as.list(environment())
})

This avoids creating the MakeListA function, which may only be used once.

> makefun <- function(flist) {
>    with(flist,
>      function() bar() + foo()
>    )
> }
> toplevel <- makefun(fListA)
> toplevel()
> 
> ## but it is not possible to naively replace functions afterwards:
> fListA$bar <- function() cos(foo())
> toplevel <- makefun(fListA)
> toplevel()
> 
> ## Error in bar() : could not find function "foo"

This is sensible.  Functions in R aren't macros.  When you say 
cos(foo()) you are assumed to mean the cos and the foo that are visible 
in the current environment.  If you had meant the one in fListA, you 
would have said so.

Duncan Murdoch

> 
> 
> Note that it's the same in the "explicit" and in the environment version.
> 
> -- Thomas P.
>



[Rd] experiments with slot functions and possible problems NOTE
Duncan Murdoch