[Rd] attributes of environments

Thomas Lumley tlumley at u.washington.edu
Wed Jul 5 19:05:13 CEST 2006


On Wed, 5 Jul 2006, Gabor Grothendieck wrote:

> On 7/5/06, Thomas Lumley <tlumley at u.washington.edu> wrote:
>> On Wed, 5 Jul 2006, Gabor Grothendieck wrote:
>> 
>> > On 7/5/06, Thomas Lumley <tlumley at u.washington.edu> wrote:
>> >> On Tue, 4 Jul 2006, Gabor Grothendieck wrote:
>> >>
>> >> > In the code below, e is an environment which we copy to f and then
>> >> > add attributes to e.  Now f winds up with the same attributes.
>> >> >
>> >> > In other words it seems that the attributes are a property of the
>> >> > environment itself and not of the variable.  Thus it appears we
>> >> > cannot have two environment variables that correspond to the
>> >> > original environment but with different attributes.
>> >>
>> >> No, we can't. The two variables are references to the same environment, 
>> so
>> >> they are the same.
>> >>
>> >> If you want the attributes to be copies rather than references then 
>> create
>> >> a list with the environment as an element and put the attributes on the
>> >> list.
>> >
>> > I realize that that is how it works but what I was really wondering was
>> > should it work that way?
>> >
>> 
>> I think it really should (and this question has come up before).  If you
>> do
>>    e<-environment()
>>    f<-e
>> 
>> then there is only one object that f and e both point to. Now, since such
>> things as S3 class and matrix dimension are implemented as attributes I
>> think you really have to consider the attributes as part of the object
>> [which is also how they are implemented, of course].  So if e and f are
>> the same object they should have the same attributes.
>
> I don't think this follows since in the other cases modifying the
> object also creates a copy.

In cases other than environments, NULL, external pointers and weak 
references a new object is (from the language definition point of view) 
created on assignment. The fact that sometimes the actual memory 
allocation is deferred is an implementation issue.

That is
   e <- 2
   f <- e

creates two different vectors of length 1, so of course they can have 
different attributes.

For environments (and for NULL, external pointers, and weak references), 
assignment does not create a new object. It creates another reference to 
the same object.  Since it is the same object, it is the same: attributes, 
values, class, etc.


>> 
>> Another reasonable position would be to disallow attributes on
>> environments (as we do with NULL, another reference object), but that
>> seems extreme.
>
> I don't think that that would solve it because there is still the issue
> of the class attribute which you can't disallow.

Of course you can. It might be inconvenient, but it's not difficult.


> In fact consider this:
>
> e <- new.env()
> f <- e
> class(f) <- c("myenv", "environment")
> F <- function(x) UseMethod("F")
> F.environment <- function(x) 1
> F.myenv <- function(x) 2
> F(e) # 2
> F(f) # 2
>
> The point is that subclassing does not work properly with environments

No, subclassing *does* work. f and e are the same object, so they have the 
same class, c("myenv", "environment"). The thing that doesn't "work" the 
way you expect is assignment:
    f <- e
doesn't create a new object, as it would for any other sort of object.

> yet subclasses of the environment class should be possible since R
> is supposed to be OO and I see no valid reason for exclusing environments
> for this.  I guess in this discussion I am coming to the realization that
> this issue really is a problem with the current way R works.

It really is the way R is designed to work. Whether it is a problem or not 
is a separate issue. Environments really are references, not values, and 
they really work differently from the way most other objects work.

 	-thomas

Thomas Lumley			Assoc. Professor, Biostatistics
tlumley at u.washington.edu	University of Washington, Seattle



More information about the R-devel mailing list