From murdoch.duncan at gmail.com  Mon Nov  7 12:49:05 2011
From: murdoch.duncan at gmail.com (Duncan Murdoch)
Date: Mon, 07 Nov 2011 06:49:05 -0500
Subject: [Rd] Accessing ENVSXP and CLOSXP while processing parsed R code
In-Reply-To: <CAApt6DK3YD9sf8+Vzx2hoYTMpMzyrttiHxVem3tDR0oF6Tms_A@mail.gmail.com>
References: <CAApt6DK3YD9sf8+Vzx2hoYTMpMzyrttiHxVem3tDR0oF6Tms_A@mail.gmail.com>
Message-ID: <4EB7C5B1.5020705@gmail.com>

On 11-11-07 5:24 AM, Rob Anderson wrote:
> Hello Guys,
>
> Following up my earlier mail where I am trying to write an alternative
> front-end for R,  I had a question about accessing the closures and
> environments in R code.
>
> Here's the function taken  and modified a little from "*Lexical Scope and
> Statistical Computing*"
>
> =====================================================================
> f<-function(){
>    Rmlfun<-function(x){
>      sumx<-  sum(x)
>      n<-  length(x)
>      function(mu)
>        n*log(mu)-mu*sumx
>    }
>    efun<-Rmlfun(1:10)
>    y1<-  efun(3)
>    print(y1)
>    efun2<-  Rmlfun(20:30)
>    y2<-  efun2(3)
>    print(y2)
> }
> =====================================================================
>
> Now assignment efun<-Rmlfun(1:10) creates a closure where
> *function(mu) n*log(mu)-mu*sumx *is returned and *sumx* and *n *are added
> to the existing environment.

That's not correct.  When you call Rmlfun, an evaluation frame 
(environment) is created.  It contains the argument x.  Then sumx and n 
are added to it.  Then the anonymous closure is created, with body 
n*log(mu)-mu*sumx, and the closure's environment is the evaluation frame 
from the call to Rmlfun.


>
> I can parse the code using *PROTECT(e =
> R_ParseVector(tmp,1,&status,R_NilValue));* where tmp is the buffer
> containing the same source. I can walk the resultant parser output and
> build and alternative Abstract syntax tree(AST).
>
> I would like to include the information about closure/environments in my
> AST so that I can possibly do some optimizations.

It's not there, except potentially.  When you call the function 
"function" to create the closure, that's when the closure is created. 
That doesn't happen at parse time.  Rmlfun is created when you evaluate 
f() and then the anonymous function is created when you call Rmlfun() 
within it.

>
> My question is, how can I get hold of this information?
>
> One thing I noticed while 'walking' through the parser output, I never
> encounter a CLOSXP (which I check using TYPEOF()) , even though in the
> above code, closure is created. Is it the case that this information is
> meant just for the internal "eval*" function and not exposed application
> writers?

No, there's nothing hidden, it just didn't exist at the time you were 
looking for it.

Duncan Murdoch



[Rd] Accessing ENVSXP and CLOSXP while processing parsed R code
Duncan Murdoch