[R] terminology for frames and environments

Gabor Grothendieck ggrothendieck at myway.com
Tue Jun 15 03:45:03 CEST 2004

There was a typo in the previous version of this message.
Pela should have been Pel.  Here it is corrected.

Peter Dalgaard <p.dalgaard at biostat.ku.dk>
> Gabor Grothendieck <ggrothendieck at myway.com> writes:
> > Thomas Lumley <tlumley <at> u.washington.edu> writes:
> > 
> > > The distinction between "environment" and "frame" is important. The frame
> > > is what you find things in with get(, inherits=FALSE) and the environment
> > > uses get(, environment=TRUE).
> > 
> > The thing I find odd about this one is that if we have:
> > 
> > e <- new.env()
> > e$x <- 1
> > f <- new.env(parent=e)
> > f$x # gives an error
> (Actually not. I get NULL)


> > then I would have expected x to be returned since f is an environment
> > and x is in that environment. On the other hand, if an environment
> > is defined to be the same as a frame (and there is some other word for 
> > an environment and its ancestors) then the above notation makes sense.
> Why? f$x is documented to be basically equivalent to
> get("x",f,inherits=FALSE). In contrast,
> > evalq(x,f)
> [1] 1
> works fine.

Well this certainly is more environment-like if one defines environment
as a frame plus ancestors but it does not address the issue that 
if f is an environment in that sense then $ "should" pick out its
components. One can define + to mean subtraction but that's not natural.

I agree that it would have been nice if environment had been used to
mean a frame plus its ancestors and class(f) was "frame", not "environment"
but, of course, that's not how it turned out.

I think its better to maintain backward compatiblity as far as possible and
make the terms suit rather than use environment in a way which is
inconsistent with the way R works.

In fact, it might have been nice if there were both a frame class and an
environment class so one could have either behavior. With this new
setup R might have worked like this:

     # create parent environment 
# (in the sense of frame+ancestors) & populate
     Pe <- new.env(): Pe$x <- 1

     # create child environment
     Ce <- new.env(parent=Pe)

     # create corresponding frames
     Pf <- as.frame(Pe); Cf <- as.frame(Ce)

     # x exists in child environment
     exists(Ce$x) # TRUE

     # but not in child frame
     exists(Cf$x) # FALSE

Unfortunately this can't be done without breaking backward compatibility
although it would still be possible to come up with a new word for
environment plus ancestors (call it the envlist class) using environment 
as a synonym for frame. In that case this example would become:

     # create parent using envlist class & populate
     Pel <- new.envlist(): Pel$x <- 1

     # create child environment+ancestors class
     Cel <- new.envlist(parent=Pel)

     # create corresponding environments (in the sense of frames)
     Pe <- as.env(Pel); Ce <- as.env(Cel)

     # x exists in child environment
     exists(Cel$x) # TRUE

     # but not in child frame
     exists(Ce$x) # FALSE

and this one is upwardly compatible with the current R.

More information about the R-help mailing list