Re: [R] Possible (ab)use of lexical scoping in R ?

From: Prof Brian Ripley <ripley_at_stats.ox.ac.uk>
Date: Sun 22 May 2005 - 01:37:01 EST

On Sat, 21 May 2005, Emmanuel Charpentier wrote:

> Dear list,
>
> I wish to define a set of functions *auxilliary* to another set of
> "main" ones, and I wonder if there is some "clever" way do do this using
> lexical scoping. Looking for that in the list's archives did not get me
> easily understood answers. Perusing MASS (1st, 2nd, 3rd and 4th
> editions!) and "Programming S" wasn't of much help either...

Well, `S Programming' (sic) is about S, and S is not lexically scoped, only the R dialect is (and much of it was not when that was written as functions in packages were re-parented).

Look at ?local for one way to do this. However, I _would_ use a namespace for anything which required more than one public function. Here is another (closely related) idea:

myenv <- new.env()
assign("bar", function(a,...) {}, envir = myenv) assign("gee", function(t,u,...) {}, envir = myenv) foo <- function(x,y,...) {

    t <- bar(y) # I hope you meant
    u <- gee(t, x,..)
}
environment(foo) <- myenv
rm(myenv)

> R easily allows to create functions local to *another* function, as in :
>
> foo<-function(x,y,...) {
> bar<-function(a,...) {
> ...
> }
> gee<-function(t,u,...) {
> ...
> }
> t<-foo(y)
> u<-gee(t,x,..)
> }
>
> In this (pseudo-)example, bar() and gee() are known in foo() but unknown
> in the main R environment, which is a Good Thing (TM) for my purposes ;
> however, they are redefined in each call to foo(), which entails some
> serious overhead.

Not so: most of the effort is in the parsing which is done once. I think you would find it hard to measure the overhead, which is counteracted by faster searching. E.g.

> system.time(for(i in 1:1000) foo(2))
[1] 1.35 0.00 1.35 NA NA
## add an internal copy of ls()
> system.time(for(i in 1:1000) foo(2))
[1] 1.3 0.0 1.3 NA NA

appears to show a small negative overhead.

> Furthermore, they cannot be used by any other function.
>
> What I want to do is so create a set of (user-invisible) auxilliaries
> used by another set of (user-visible) "main" functions. I might also
> wish sometimes to create a such a set of data.
>
> (Common) Lisp and Scheme allow this easily. For example, in Common Lisp,
> I could use :
>
> (flet ((bar (a)(...))(gee (t u)(...)))
> (defun foo(x y)( ...))
> (defun quux(m n ...)(...)))
>
> Now (barring syntax errors I may have slipped in the above
> pseudo-example (my Lisp is rusty)), foo and quux are known in the main
> environment, can both call bar and gee, which are not visible. Lisp also
> allows me to do a similar thing for "data" (with let()) and even macroes
> (with macrolet()). Variants such as let*() allow, IIRC, to play tricks
> with evaluation order (e. g. mutually calling "local" functions).
>
> I am aware that one may achieve the same thing in R by creating a
> package with its own namespace and exporting relevant items.However, in
> my case, that would be trying to cut one's steak with a sawmill's ribbon
> saw.
>
> Are there way(s) to create a new environment, defining local functions
> (or data) in this environment and the "main" functions in the parent
> environment (or the global one) while still in the local environment ?
>
> Emmanuel Charpentier
>
> PS : I'd appreciate Cc's to my address, since I am not on the list and
> read it through the Web interface.
>
> PPS : Shouldn't "S programming" be a bit overhauled ? at the time of its
> writing, R 0.90 was current...

You seem unaware of how little difference that has made -- very little is superseded, although some additions could be made. Revisions have been planned (and updates written) but more progress depends on the first author's health and time.

-- 
Brian D. Ripley,                  ripley@stats.ox.ac.uk
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595

______________________________________________
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
Received on Sun May 22 01:42:18 2005

This archive was generated by hypermail 2.1.8 : Fri 03 Mar 2006 - 03:31:59 EST