From jmc at research.bell-labs.com  Wed Aug 13 19:17:13 2003
From: jmc at research.bell-labs.com (John Chambers)
Date: Thu Aug 14 00:17:24 2003
Subject: [Rd] s4 methods and base
References: <8CBAA121CEB4D5118CB200508BB2BBEF0317E8F4@xmx8lonib.lonib.commerzbank.com>		<3F380492.ED19612C@research.bell-labs.com>
	<3F391DC0.4010701@bank-banque-canada.ca>
	<3F396990.99F9E536@research.bell-labs.com>
	<3F3A45F5.7070202@bank-banque-canada.ca>
Message-ID: <3F3AB8E9.77E1AA12@research.bell-labs.com>

Paul Gilbert wrote:
> 


......................
>
> 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?

No, I'm not using it loosely, but I am using it as it's used for S4
classes.

"contains" is an argument in defining a class via setClass().  Its
meaning is essentially the mathematical one, as in "Set B contains set
A."  If we think of a class as corresponding to a set of slots, that is,
a set of (name, class) pairs, then "class B contains class A" says that
the set of slots for B contains that for A.

"extends" is a more general concept in the S class system.  See
Programming with Data for details and examples, but the essential
meaning of "class B extends class A"  is that any instance of B can be
used when an instance of A is needed.  As I said, "contains" is the most
common but not the only way to create an "extends" relation.

"inherits" is an S3 concept defined in Statistical Models in S.  In
practice, it says ONLY that "A" appears in the class attribute for a
particular object, and not necessarily as the first string.  One of the
problems with an informal, instance-based, system is that there is no
way to verify what if anything inheritance implies.

> 
> >
> >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.

If we rephrase the question as "can an S4 class have objects from S3
classes as slots", the answer is yes, but you should "register" the S3
classes to the formal class system, by calling setOldClass (see the
online documentation).  That's what we did for the base package's
classes, as discussed re John Marslan's mail. So, e.g.,
  setOldClass(c("ordered", "factor"))
to register the S3 class "ordered" with its inheritance from "factor".

Registration isn't enforced yet, but I would like to do so, in order to
require that all the slots in a class definition correspond to defined
classes.

> 
> >>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.

There are ways to provide a degree of "automatic" class extension for
features that are midway between universal necessities and purely
specialized techniques.  I'm not quite convinced this is a sufficiently
desirable mechanism, but in any case a way to start would be a nice
simple implementation, e.g., as a class with corresponding methods, say,
to extract or assign a "note"; i.e., for generic functions `note(object,
name)' and `note(object, name) <- value'.

John
> 
> Thanks again,
> Paul
> 
> >Regards,
> > John
> >
> >
> >>Thanks,
> >>Paul Gilbert
> >>
> >>______________________________________________
> >>R-devel@stat.math.ethz.ch mailing list
> >>https://www.stat.math.ethz.ch/mailman/listinfo/r-devel
> >>
> >>
> >
> >
> >

-- 
John M. Chambers                  jmc@bell-labs.com
Bell Labs, Lucent Technologies    office: (908)582-2681
700 Mountain Avenue, Room 2C-282  fax:    (908)582-3340
Murray Hill, NJ  07974            web: http://www.cs.bell-labs.com/~jmc


[Rd] s4 methods and base
John Chambers