Path: utzoo!attcan!uunet!nih-csl!lhc!mimsy!haven!udel!wuarchive!sdd.hp.com!elroy.jpl.nasa.gov!lll-winken!unixhub!shelby!neon!craig From: craig@Neon.Stanford.EDU (Craig D. Chambers) Newsgroups: comp.object Subject: Re: Void references Message-ID: <1990Nov15.011702.25087@Neon.Stanford.EDU> Date: 15 Nov 90 01:17:02 GMT References: <1990Nov7.220902.13393@Neon.Stanford.EDU> <454@eiffel.UUCP> Organization: Stanford University Lines: 114 In article <454@eiffel.UUCP> bertrand@eiffel.UUCP (Bertrand Meyer) writes: > Apparently this is easier in Self because it's > not really classes but objects. > But here I quit. Object-oriented programming > as I understand it has little to do with objects; > it is really about classes. Why one should try to have > O-O Programming without classes, the major facility of > the method, is beyond my understanding. I should probably > have kept my mouth shut, but it's too late. I'm glad you didn't. There seems to be a common misconception that languages without classes cannot be used for normal kinds of object-oriented programming, in a "structured" way. This, I'd argue, is not the case. The linguistic facility in many object-oriented languages called a "class" provides a number of features: Repository for shared behavior (e.g. inherited methods) Repository for shared state (e.g. class variables) Template for format of instances (e.g. instance variables) Object containing instance-independent behavior and state (e.g. class methods, class variables) And for statically-typed languages: Specification of interface (e.g. signatures of methods, deferred methods) All of these features are useful, and any reasonable object-oriented language should provide these mechanisms somehow. Class-based languages tie these features together into one all-consuming linguistic construct, the class. This in itself is not a real problem. The problem arises when one class is defined as a subclass of another. In most existing class-based languages, it is not possible to inherit only part of the aspects provided by the superclass; it is impossible in most class-based languages to inherit the behavior of a superclass (i.e. the methods) but not the representation. For example, suppose a new Rectangle class wants to inherit most of the implementation of the existing Polygon class, but replace the list-of-vertices representation with four integers. In most existing class-based languages, the Rectangle class would be forced to accept the vertices instance variable as well. Trellis/Owl is an example of a class-based language that does not suffer from this problem (at least as documented in the manuals I have; perhaps the implementation is not this smart yet). Languages with extensive metaclass and reflective support, like CLOS, can probably solve this problem as well by doing extra programming at the metaclass level, but this seems a bit complicated for what should be a simple task. Another example of two facilities being intertwined in some existing class-based languages is the inheritance of implementation and interface as a unit (i.e. subtyping = submoduling). The specification part of classes must be inherited if the behavior part is inherited, and vice versa. This issue has been beaten to death already. In a classless language like Self, you'd use separate objects to provide each the above facilities. One object holds shared behavior and shared state for an abstraction (called the traits object). Another object serves as a template for instances of the abstraction (called the prototype). Depending on the mood of the Self programmer, instance-independent behavior may be included in the traits object or moved out into a separate object. Objects are also used as name spaces, so that a simple message like "traits rectangle" will evaluate to the rectangle traits object. Object inheritance subsumes the subclassing hierarchy, the instantiation hierarchy, and even the variable name scoping rules. Since different objects support different aspects of classes, refining objects can inherit behavior without representation, or vice versa, by inheriting from only the appropriate objects. In Self defining two or three objects for what would normally be part of a single class declaration is a bit more verbose (by a few lines), but future classless languages need not have this problem. People who've seen some of our talks on Self, or who have read some of our papers, sometimes feel like we've just re-invented classes and called them traits objects. In a way, they're right: traits objects are similar to class objects in that both fulfill the need to provide shared behavior. But classes bring along lots of other baggage (like representation) that may not always be needed or desired. What we've really done is to break up classes into several more primitive pieces that can be combined in useful ways that aren't possible in typical class-based languages. My feeling is that "ideal" class-based languages and "ideal" classless languages turn out to be very similar. Ideal class-based languages would allow the different facilities provided by the class construct to be mixed and matched in subclasses (thus extending the idea of two kinds of inheritance links that I proposed earlier to allow inheritance of particular aspects of classes). Ideal classless languages might be able to define some objects as "abstract" (implying use as a traits object) and other objects as "concrete" (implying use as a prototype object); the syntax for defining these objects could be designed so that a single declaration would define several related objects. In the end, programs in the two kinds of languages would end up looking remarkably similar, and similar kinds of power and flexibility are afforded by both languages. One remaining difference is that class-based languages include an instantiation hierarchy while classless languages do not; I'm not sure how important this distinction is. Another difference is that classless languages support inheritance from other objects (either abstract or concrete objects), while class-based languages only support inheritance from classes (analogous to inheriting from only abstract objects). This distinction may be more interesting, and in the end ideal classless languages may win out over ideal class-based languages for this very reason. -- Craig Chambers P.S. A less speculative paper on this topic, "Organizing Programs without Classes," is available via anonymous ftp from otis.stanford.edu.