Introducing more meaning into inheritance

Alan C. Kay alank at
Sun Apr 26 19:11:22 UTC 1998

Kris --

At 12:58 PM -0400 4/26/98, Krisztian Flautner wrote:
>> (b) another thing we could do is to try to introduce more meaning into
>>     inheritance. Right now there is no "algebra" that will tell us anything
>>     useful about what a subclass might be relative to its super classes.
>Could you elaborate some more on this? I don't quite understand what you
>When I think of added meaning related to inheritance, C++ comes to mind.
>There it is used both as a means of code reuse and type extension, causing
>designs to rely heavily (often unnecessarily) on inheritance.
>Could you give some example about what type of added meaning you are
>thinking about?

Here are a few problems in the naive inheritance systems we use today ...

(a) confusions of Taxonomy and Parentage, of Specialization and Refinement, of Parts and Wholes, of Semantics and Pragmatics.

When a sender sends a message, the receiver is very much like a server on a network -- it will respond to a variety of messages and not be able to respond to others. All of its functionality is logically "inside". 
The question at hand is "how should the interior of an object be best structured"?

The hierarchy of SmallInteger is


of Fractions is


done this way in Smalltalk because any kinds of Integers should work as components of a Fraction. Other OOP systems have defined Fraction as a subclass of Integer. Also note that SmallInteger, LargePositiveInteger, etc. are pragmatic refinements to Integer, but that Number is in a different "Linneaean" category from Magnitude, (as Magnitude is from Object).

All this makes
      Foo subClass: #Bar
a difficult line of code to understand -- even if you really understand Foo, it is not at all clear what Bar will be like. It could be very much like Foo or not at all. Inheritance is a weak notion in most OOP languages. Even if it has methods that over-ride those of Foo, there is no enforcement of any kind of polymophic meaning (aBar print, for example, could literally have any meaning).

What if we have multiple inheritance, and we send the message "print"? What will happen? In many OOP systems the first occurance of a print method along one chain will be the only one called, even though this is a very poor rendering of meaning in this case. Even a blind linear rendering (invoke all the print methods you can find on all the chains) will likely be more to the point.
     Just as the existence of classes in Simula implied there should be a Class Class and a Class Object (we eventually figured out what they should be in Smalltalk), the existence of polymophism in a OOP language really implies there should be eg a Class Print whose instances are the print methods that are added to each class. These allow code to be written as in nonconstrained methods, but they also have powers to try to enforce the polymorphism of "print" and very likely to be able to figure out reasonable combination actions in the case of multiple inheritance.

Consider the semantics of an object. Much of its meaning can come from its parts (instance variables in Smalltalk). There are many cases where inheritance through such slots is quite reasonable and useful. The existance of slot classes (as alluded to above) and an inheritance algebra for being able to say to the system what should happen (and to the programmer what should be expected) would be very useful, and would make things more clear.

Just from these few examples, I think it is clear that there are "inheritance properties and operations" that would make things much clearer, and commit far fewer category errors than we do now. Some of the early experimental OOP systems in the 70s (like Flavors and LOOPS) tried various ways (like "mixins", etc.) to give more meaning to inheritance. On the other hand, a system like SELF (which has many features worthy of admiration) goes much much too far in the opposite direction (e.g. to have the PARENT links actually be visible). This is a confusion of levels. Even if such metalinks are there, it should take more special pleading with a system to allow J. Random Programmer to willy nilly make a metachange under program control. One could also argue that Smalltalk doesn't have enough in the way of metacontrol and forces the programmer too low in the VM to make such changes.

The whole issue is similar to that of types. Not having anything (like LISP) puts one too much in a kind of assembler. The naive way (like Pascal, etc.) is too restrictive. Classes are much better in allowing one to state intentions and control operations but allow quite a bit of flexibility. We don't yet have a similar solution to the problems of factoring and combining "meanings".



More information about the Squeak-dev mailing list