[Rd] s4 methods and base

Robert Gentleman rgentlem at jimmy.harvard.edu
Wed Aug 13 11:30:11 MEST 2003


On Wed, Aug 13, 2003 at 10:06:45AM -0400, Paul Gilbert wrote:
> John Chambers wrote:
> 
> >Paul Gilbert wrote:
> >  
> >
> >>John
> >>    
> >>
> >>>But maintainers of software using S3 methods and classes
> >>>might want to consider conversions or partial conversions, when and if
> >>>they decide to revise the software.
> >>>      
> >>>
> >>I'm curious about the logistics of a partial conversion. Initially I
> >>think I will avoid classes that inherit from other classes. But what
> >>general approach would you suggest for classes that have an object of
> >>another class in their structure. Can the larger object be an S4 class
> >>and the contained object an S3 class, or would you start the other way
> >>around, or is it not possible?
> >>    
> >>
> >
> >I would think it's wise to imagine converting all the functions in an S3
> >inheritance "tree" at the same time.
> >
> There is no inheritance in the S3 sense when an object contains an 
> object of another class. Am I missing something? Are you using this term 
> loosely or is there necessarily inheritance in S4 when one object 
> contains another object?
> 

  In this instance I have to say that it is a good idea to try some of
  these things out, to read John's book, or some other books on object
  oriented programming or to look at some existing packages that use
  S4 methods. There is rather a lot of ground you are trying to cover
  in your questions.

  Inheritance (or lack of it) is directly under the control of the
  programmer. The difference in going from S3 to S4 is that you
  actually can control this in a systematic way. If I have an object
  of class "a", I can extend it in many ways. One might be to create a
  new class "b", say, that adds a new slot (or two). 

  For example,
 
   setClass("a", representation(d="numeric"))
   setClass("b", representation(e="character"), contains="a")

  so that b extends a and instances of a have one slot named d, while
  instances of b have two slots, one named d and one named e.
  If we want to call the generic function foo, and it has a method for
  class a objects, but not for class b objects then we would use the
  method for class a (one of the important points of inheritance).

  Now, I could get b's in other ways,

  setClass("b2", representation(d="numeric", e="character"))

  this class b2 does not extend the class a above (but it looks very
  similar to the class b previously defined). Instances from the two
  would be almost indistinguishable - but they are very different in
  important ways.

  I can also do the following:

  setClass("b3", representation(d="a", e="character"))

  so that the d slot in this case contains objects of class "a"
  but in no way does this class b3 extend class a.

  Calling my generic foo, as described above will not dispatch to the
  a method, it will either find a b method or call the default handler
  (usually an error message at that point).

  Using inheritance usually gives you cleaner code and less of it to
  write. But it requires that you think about your classes and methods
  before you start writing them.

  In S3 there is no real sense of inheritance (which is why we are
  moving to S4).

  Robert


> >
> >The basic point is that ordinary formal classes have to have an
> >unambiguous "structure"; that is, known slots each having a known class.
> >
> >So the S3 class can't be extended by an S4 class, since the latter
> >wouldn't then have a known structure.
> >
> >The other direction is technically feasible, but it feels like a bad
> >idea in general.
> >
> I can see that it feels bad, but it seems like the only way to do a 
> partial conversion. My problem is that it is much easier to do a big 
> project in small bites.
> 
> >>Also, would you suggest converting to namespaces before or after
> >>converting to S4 classes?
> >>    
> >>
> >
> >At the moment, they don't work together, so it really amounts to
> >choosing which matters most to a given project.
> >
> >The hope is to make them work together for 1.8, but that's still a hope
> >rather than a certainty.
> >
> >  
> >
> >>>With S4 classes, every object has a single class, with an explicit
> >>>definition.  That class can have superclasses  (defined as the classes
> >>>this class contains).
> >>>      
> >>>
> >>(newbie question) Are you using "contains" as a synonym for "extends,"
> >>    
> >>
> >
> >Yes, roughly.
> >  
> >
> >>meaning that many classes can contain the same superclass, or is this
> >>intending to indicate that the logic is the reverse of (my understanding
> >>of) S3 logic?
> >>    
> >>
> >
> >The S language terminology "Class B extends class A" is analogous to
> >"Class A is a superclass of class B" in other languages.  Saying "Class
> >B contains class A" is a special form of "extends" (the most common
> >one), where B has all the slots of A, and perhaps others as well.  The
> >setIs() function allows a more general version of "extends" that doesn't
> >depend on the data structures being compatible.
> >
> Now if I understand this correctly, and to be pedantic, one would say an 
> object of class B contains and object of class A, and,  the definition 
> of class B extends the definition of class A. Or, said differently,  a 
> class A object is a subset of a class B object, and a class A definition 
> is a superclass of a class B definition. Does that make sense?
> 
> >>> - classes that don't have multiple strings in the class attribute can
> >>>often just be converted to a non-virtual S4 class, so long as objects
> >>>always have the same attributes.  Attributes go into slots (the slot
> >>>must have some specified class, but there are ways to allow some
> >>>variation in the actual type of data in the slot).
> >>>      
> >>>
> >>(newbie question) I often use attributes to stick "extra" information on
> >>an object, like the date of retrieval from a database onto a matrix. If
> >>the matrix is an S4 matrix class, does this mean that I have to define a
> >>new class in S4 that extends the matrix class in order to stick on extra
> >>information?
> >>    
> >>
> >
> >A good question, which points out some of the tradeoffs involved.  Yes,
> >if you want to work in terms of ordinary formal classes, the set of
> >slots (the "structure") is determined by the class, not by the
> >individual object.
> >
> >It's fundamental to most formal class systems that objects from a class
> >have a known structure, in our case meaning that the slots are fixed as
> >to name and class.  This is indeed more restrictive than the traditional
> >S approach (dating back well before "white book" classes) of attaching
> >attributes, on a per-object basis, while retaining the underlying
> >"structure" (a matrix, as in your example).
> >
> >It's a basic difference, and the formality has been adopted in many
> >languages because it makes possible operations that a less formal system
> >can't do, especially in terms of automating some computations.  Two
> >examples:  an object can be tested for being a valid member of a class;
> >and methods can be generated automatically to coerce an object to a
> >superclass, or to replace the part of an object that corresponds to a
> >superclass.
> >
> >There are of course ways to add general annotation to a class, e.g., by
> >having a slot for miscellany (that slot might be a named list).
> >
> Would there be a point in formalizing this so that everyone does not 
> need to define extensions of all the basic classes with an extra 
> miscellany slot. I'm sure this sounds like herecy, but the alterative is 
> that many people will be doing somewhat similar things using different 
> class and slot names, and there will be a lot of unnecessary 
> incompatibility among packages.
> 
> Thanks again,
> Paul
> 
> >Regards,
> > John
> >  
> >
> >>Thanks,
> >>Paul Gilbert
> >>
> >>______________________________________________
> >>R-devel at stat.math.ethz.ch mailing list
> >>https://www.stat.math.ethz.ch/mailman/listinfo/r-devel
> >>    
> >>
> >
> >  
> >
> 
> ______________________________________________
> R-devel at stat.math.ethz.ch mailing list
> https://www.stat.math.ethz.ch/mailman/listinfo/r-devel

-- 
+---------------------------------------------------------------------------+
| Robert Gentleman                 phone : (617) 632-5250                   |
| Associate Professor              fax:   (617)  632-2444                   |
| Department of Biostatistics      office: M1B20                            |
| Harvard School of Public Health  email: rgentlem at jimmy.harvard.edu        |
+---------------------------------------------------------------------------+



More information about the R-devel mailing list