MORE ON TYPE INHERITANCE
with Chris Date

 

 

From: DN
To: Editor

 

I guess everyone somehow feels the need to weigh in on this, so I won't be resisting the temptation.

 

Trying to step back from the discussion a bit, it seems that the disagreement does from a large part stem from the difference of perspectives--one of a perfectly logic world where everything is as it seems, and the other based in the less-than-perfect reality of a particular implementation of a particular model of type inheritance.

 

Despite your insistence that your original article is not an attack on C++ in particular, the problem is one that stems from how C++ defines inheritance (it is probably a reasonable guess that most OOPLs share, as far as it is relevant, the same model, but not pretending to be an expert in other OOPLs I will restrict my remarks to C++). In particular, inheritance does not accurately model subtypes, nor do I believe it is necessary for it do so. C++ has no keyword that says "A is a subtype of B". It has a keyword (well, actually a symbol, i.e. the humble colon!) that says A must support all the operations and contains all the data associated with B. By this definition, circle cannot inherit from ellipse, no matter how plainly obvious it is that a circle is a type of ellipse. The problem is that for a number of cases C++ inheritance can model subtypes, and sometimes, particularly for the uninitiated, it is the easiest or most obvious way to explain it. But to pretend that it is designed for this purpose is to fool oneself, and the circle/ellipse dilemma perfectly demonstrates this.

 

A model of inheritance whose purpose was to model subtyping would, as you suggest, have to be somewhat different. It would say "A must support all the read-only operations of B", and nothing much more. While that solves the subtyping problem, it would be relatively useless in an OOPL. It could be added as an extra "method" of inheritance, but I doubt it would find too much use in real applications. It is still not entirely satisfying, as it would require a circle to support the read-only operations "get major axis" and "get minor axis", which are not operations one would ever expect to perform on something you knew already was a circle. But if C++ supported this form of inheritance, then this is exactly what you would use to model the concept "a circle is a special type of ellipse". C++ does not have this form of inheritance, nor any easy way to model this concept, so the easy solution is simply not to model this concept. In reality, it is of dubious use in an application. The typical case of a drawing program is simply not going to care whether something is a circle or an ellipse, in fact I know of no drawing program that treats them differently (often there is a key you hold down to "constrain" an ellipse to be circular, but after that you wouldn't, for example, expect to see a description of the object declaring it to be a circle with such and such a radius).

 

There may, of course, be possible applications where the distinction is useful, but in all my C++ programming years I have never come across this, or a similar problem. I suspect there is only so much breath (as it were) wasting on the subject!


 

Chris Date Responds: DN wrote a pleasant and unusually coherent commentary on the circles-and-ellipses debate. Indeed, I found myself in considerable sympathy with much of DN's main argument. To paraphrase somewhat, that argument was that C++ and other OO languages aren't really trying to deal with subtyping in their approach to inheritance--that's not what they want to do. In other words, they're more interested in software engineering matters--in particular, with such issues as code reuse--and not so interested in "models of reality" as such (this latter, perhaps being a matter of more interest to database professionals).

 

However, DN then went on to say that "A model of inheritance whose purpose was to model subtyping ... would be relatively useless in an OOPL ... There may, of course, be cases where [such a facility] is useful, but in all my C++ programming years I have never come across this." There are a couple of (major) points I want to make in response to these remarks:

 

First, Hugh Darwen and I have never claimed that our brand of type inheritance would be useful "in an OOPL." Au contraire, in fact: We recognize that our brand of inheritance doesn't work with objects (at least inasmuch as one can agree on what "objects" are). To be specific, if using "an OOPL" means using objects that have object IDs, then we recognize that specialization by constraint (S by C) and generalization by constraint (G by C)--see my response to KU earlier--can't be made to work. Since we regard S by C and G by C as essential components of a good model of subtyping and inheritance, we conclude that "OOPLs" (or objects) and a good model of subtyping and inheritance are incompatible concepts. This is one of several reasons why we reject objects, as such, entirely in THE THIRD MANIFESTO (see Appendix G of the book for arguments and examples in support of the foregoing position.)

 

Second, there's an implicit wider suggestion in DN's letter (possibly unintended) to the effect that a model of inheritance whose purpose was to model subtyping would be relatively useless in general (i.e., not just "in an OOPL"). Well, here I'd like to observe that, in sharp contrast with this position, Hugh Darwen and I have discovered the following. 

 

a.      Our brand of inheritance provides an elegant solution to a certain problem that arises in connection with something we're currently very interested in: namely, the proper handling of temporal data. What's more, we haven't seen any other "good" solution to the problem in question in the literature.

 

b.      Our brand of inheritance also deals elegantly with a somewhat vexing problem that arises in connection with questions such as this one: Are NUMERIC(3) and NUMERIC(2) different types or not?

 

c.      Preliminary investigations seem to show that our brand of inheritance also provides an elegant approach to certain important problems that arise in the world of geospatial applications.

 

(We plan to publish our thoughts on these matters as soon as we can, but don't hold your breath.)

 

Finally, let me add that we can do "C++-style inheritance" in our model; we just don't call it inheritance (or subtyping). In fact we don't explicitly call it anything at all, but what I have in mind is akin to what I believe some people call delegation. Appendix F of the book already mentioned gives some examples; Appendix G also discusses the issue.

 

 

Posted 05/03/02

 

 

 

[ABOUT] [QUOTES] [LINKS]