Bug 8053 - S4 setClass with prototypes " issues"
Summary: S4 setClass with prototypes " issues"
Status: NEW
Alias: None
Product: R
Classification: Unclassified
Component: S4methods (show other bugs)
Version: old
Hardware: All All
: P5 normal
Assignee: Jitterbug compatibility account
URL:
Depends on:
Blocks:
 
Reported: 2005-08-05 22:06 UTC by Jitterbug compatibility account
Modified: 2005-08-06 00:06 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jitterbug compatibility account 2005-08-05 22:06:47 UTC
From: Berton Gunter <gunter.berton@gene.com>
To R-Developers:

I wish to report what I believe are inconsistencies between Green Book
descriptions and R methods behaviors. I **realize** that R does not
guarantee total consistency with the Green Book; therefore I leave it to you
to decide whether any of this is a bug, design choice, or a need for
additional documentation -- or whether I have simply misread or overlooked
existing explanations. If the latter, I apologize for the error, but it was
not for a want of effort.

The issues all revolve around the setClass('xxx',prototype=...) without any
slots construction. All references are to the Green Book. R 2.1.1 (on
Windows)

1. Classes so defined (with protype, no slots) are not instantiated as
described on the bottom of p.289. In particular, the following example from
the book fails:

> setClass('sequence',prototype=numeric(3))
[1] "sequence"
> new('sequence',c(1,51,10))
Error in initialize(value, ...) : cannot use object of class "numeric" in
new():  class "sequence" does not extend that class
 
2. I have been unable to find any Help documentation about the proper method
to instantiate classes defined by prototypes without slots. Experimentation
showed that only one of the two approaches on the bottom of p.289 worked:

> setClass('foo',prototype=numeric())
[1] "foo"
> z<-new('foo')
## new() works as it should
> z
An object of class "foo"
numeric(0)

## But now try this ...
> z<-1:3
> is(z,'numeric')
[1] TRUE
## Hence, if R followed the book's statement that "For this to work,
'object' must either be suitable as a prototype for 'myClass or belong to a
class that can be coerced to 'myClass.'" (Note, I interpret this to mean
that either of these conditions are sufficient for either of the approaches
shown).

> as(z,'foo')
Error in as(z, "foo") : no method or default for coercing "integer" to "foo"

## But
> class(z)<-'foo'
> z
An object of class "foo"
[1] 1 2 3

I was unable to find documentation for this behavior in R, assuming that
this is not a bug. If it's a bug, it should be fixed, of course; if not, I
think the behavior should be documented, perhaps in setClass.

3. Finally, and most disconcertingly, The Green Book says (p.288):

"... We do NOT want a 'sequence' object to be interpreted as a numeric
vector ... Doing arbitrary arithmetic on the object, for example would be
disastrous...

The use of prototypes without representations allows the class designer to
limit the legal computations on objects made up of numeric data..."

As I read this, this should mean that the following should fail, but it
doesn't (continuing the above example):

> z+1
An object of class "foo"
[1] 2 3 4

Again, if this is not a bug, I think that this lack of adherence to the
Green book should be documented in R. May I say, however, that I wish R had
implemented the book's prescription.


-- Bert Gunter
Genentech Non-Clinical Statistics
South San Francisco, CA
 
"The business of the statistician is to catalyze the scientific learning
process."  - George E. P. Box
 



Comment 1 Jitterbug compatibility account 2005-08-06 00:06:55 UTC
From: John Chambers <jmc@R-project.org>
Well, let's say R is currently picky when only a prototype is supplied.

The following is either a workaround or a revised, fussier requirement 
for the example mentioned, depending on your interpretation.

R> setClass("sequence", representation(.Data="numeric"), 
prototype=numeric(3))
[1] "sequence"
R> xx <- new('sequence',c(1,51,10))
R> xx
An object of class “sequenceâ€
[1]  1 51 10
R> is(xx, "numeric")
[1] FALSE

So far, so good.  But there are a couple of catches.

The resolution of prototype and representation is currently somewhat of 
a mess in the R implementation.  There's been some discussion of 
cleaning it up, hopefully moving ahead from the Green Book description 
to a more coherent definition.  So whether eventually one could (or 
should) omit the representation() part remains to be seen.

The other relevant flaw currently is that S4 objects have no special 
internal representation in R, so there's effectively no way to keep 
primitive operations from working on them. (The general & notorious 
example is that xx[] always returns something on an S4 object, even when 
it shouldn't.)  In the current case, the problem is that, in spite of 
not extending "numeric", low-level arithmetic is still done.

R> xx+1
An object of class “sequenceâ€
[1]  2 52 11

Something basic is needed here, in the code for primitives, but so far 
objections re efficiency have prevented doing anything.

Meanwhile, those more interested in getting something done than 
discussing, would need to implement explicit methods for the new class 
that either re-interpret or block the primitives that shouldn't happen 
in the standard way.


gunter.berton@gene.com wrote:

> To R-Developers:
> 
> I wish to report what I believe are inconsistencies between Green Book
> descriptions and R methods behaviors. I **realize** that R does not
> guarantee total consistency with the Green Book; therefore I leave it to you
> to decide whether any of this is a bug, design choice, or a need for
> additional documentation -- or whether I have simply misread or overlooked
> existing explanations. If the latter, I apologize for the error, but it was
> not for a want of effort.
> 
> The issues all revolve around the setClass('xxx',prototype=...) without any
> slots construction. All references are to the Green Book. R 2.1.1 (on
> Windows)
> 
> 1. Classes so defined (with protype, no slots) are not instantiated as
> described on the bottom of p.289. In particular, the following example from
> the book fails:
> 
> 
>>setClass('sequence',prototype=numeric(3))
> 
> [1] "sequence"
> 
>>new('sequence',c(1,51,10))
> 
> Error in initialize(value, ...) : cannot use object of class "numeric" in
> new():  class "sequence" does not extend that class
>  
> 2. I have been unable to find any Help documentation about the proper method
> to instantiate classes defined by prototypes without slots. Experimentation
> showed that only one of the two approaches on the bottom of p.289 worked:
> 
> 
>>setClass('foo',prototype=numeric())
> 
> [1] "foo"
> 
>>z<-new('foo')
> 
> ## new() works as it should
> 
>>z
> 
> An object of class "foo"
> numeric(0)
> 
> ## But now try this ...
> 
>>z<-1:3
>>is(z,'numeric')
> 
> [1] TRUE
> ## Hence, if R followed the book's statement that "For this to work,
> 'object' must either be suitable as a prototype for 'myClass or belong to a
> class that can be coerced to 'myClass.'" (Note, I interpret this to mean
> that either of these conditions are sufficient for either of the approaches
> shown).
> 
> 
>>as(z,'foo')
> 
> Error in as(z, "foo") : no method or default for coercing "integer" to "foo"
> 
> ## But
> 
>>class(z)<-'foo'
>>z
> 
> An object of class "foo"
> [1] 1 2 3
> 
> I was unable to find documentation for this behavior in R, assuming that
> this is not a bug. If it's a bug, it should be fixed, of course; if not, I
> think the behavior should be documented, perhaps in setClass.
> 
> 3. Finally, and most disconcertingly, The Green Book says (p.288):
> 
> "... We do NOT want a 'sequence' object to be interpreted as a numeric
> vector ... Doing arbitrary arithmetic on the object, for example would be
> disastrous...
> 
> The use of prototypes without representations allows the class designer to
> limit the legal computations on objects made up of numeric data..."
> 
> As I read this, this should mean that the following should fail, but it
> doesn't (continuing the above example):
> 
> 
>>z+1
> 
> An object of class "foo"
> [1] 2 3 4
> 
> Again, if this is not a bug, I think that this lack of adherence to the
> Green book should be documented in R. May I say, however, that I wish R had
> implemented the book's prescription.
> 
> 
> -- Bert Gunter
> Genentech Non-Clinical Statistics
> South San Francisco, CA
>  
> "The business of the statistician is to catalyze the scientific learning
> process."  - George E. P. Box
> 
> ______________________________________________
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 

Comment 2 Jitterbug compatibility account 2005-08-16 16:55:00 UTC
Audit (from Jitterbug):
Tue Aug 16 11:55:00 2005	ripley	moved from incoming to S4methods