From: robert@slipknot.rain.com (Robert Reed)
Subject: Re: Const Inheritance
Reply-To: robert@slipknot.rain.com.UUCP (Robert Reed)
Organization: Home Animation Ltd.
Date: Fri, 6 Nov 1992 02:19:38 GMT

In article <1992Nov05.165658.34729@Cookie.secapl.com> frank@Cookie.secapl.com (Frank Adams) writes:
|In article <BwwvMw.DDC@slipknot.rain.com> robert@slipknot.rain.com.UUCP (Robert Reed) writes:
|>I have not violated the intended semantics, I have generalized them, within
|>reasonable confines of the language.
|
|Since I'm giving the example, I know what the intended semantics are.  If I
|am defining the Rectangle class in a context where I can make assertions, I
|will assert that setWidth does not change the height, and vice versa.  This
|is the intended semantics, even though the assertions are not available in
|the language.

Well, EXCUSE ME!  It's true that you as the designer define the intended
semantics, but it is also true that I as a potential user will, in the absence
of further documentation, assume a semantic content based on the cues I get,
such as function names.  To me, a square still has a width and a height, but
they just happen to be constrained to be the same.  If C++ had declarative
assertions, I would expect that placing an assertion on the width and height of
a Square should not affect its base Rectangle class.

|void setDimensions(Rectangle& r, int x, int y) {
|    r.setWidth(x);
|    r.setWidth(y);
|}
|
|I expect this function to work: after it is called, r.width() should be x,
|and r.height() should be y.

(I believe the 2nd setWidth() should be a setHeight().)   I see nothing in my
counter-proposal which would deny the operation of this function.

|>|>  Alternatively, you could make Rectangle a subclass of
|>|>Square, define a setPrimaryDimension(int) for Square and add
|>|>setSecondaryDimension(int) for the specialized Rectangle class.
|
|There is another problem with this, if I decide to generalize a bit: I may
|want to define:
|
|    template<class WidthT, class HeightT>
|    class Rectangle {...}
|
|    template<class SideT>
|    class Square : public Rectangle<SideT, SideT> {...}
|
|In this case, Rectangle cannot inherit from Square; it would have to change
|the types of the instance variables.  This is not an altogether artificial
|example; I worked on a word processor (not written in an O.O. language) in
|which horizontal and vertical distances were expressed in different units.
|(This program had no use for squares, however.)

If your intent is to use Squares on a system with different horizontal and
vertical dimensions, then even your scheme of Const Inheritance doesn't solve
the problem.  You still have to deal with how to specify a square.  Is it
expressed in horizontal or vertical units?  Or both?  If you're going to
constrain the problem so as to exclude alternate solutions, make sure your own
solution still works.

|>| I don't mean to imply that this construct is necessary to create a usable
|>| class hierarchy; just that it seems to me to produce a cleaner
|>| specification thereof.
|>
|>That's not all I said in my last note.  My claim was that your language
|>enhancement is a partial feature which muddies the specification (by creating
|>anartificial restriction on inherited virtual functions to those that are
|>declared const), thus complicating the inheritance rules while providing no
|>clear advantage.
|
|See my followup to my original article; it provides a point of view under
|which the restriction seems natural.

I have read through your followup, and it doesn't fix what I see as an
artificial constraint imposed by your syntax.  If I understand your basic
postulate, it is: there are certain subclasses of desired classes that inherit
functions from their bases that violate closure of the subclasses (i.e.,
application of these functions result in objects which violate assertions of
the subclass) and that to solve this problem we should permit the subclasses to
exclude ANY function that modifies object data, thereby preventing the
inclusion of closure-violating functions.

My claim is still that this a brutish approach to a problem that has been
solved in many other languages, such as Modula-3, Eiffel, etc.; that is,
selective inheritance.  As such, const inheritance is a partial feature.  In
the example we have been abusing, all you really want to restrict is CERTAIN
geometry modifying functions--not even all of them.  For example, shouldn't I
be able to define a Rectangle::setScale() function which could be inherited by
Square?  It would change variables but not affect the geometric constraints
you've expressed concern about.  How about a Rectangle::setBoundaryColor()
function?  This is a nongeometric function and so should be equally usable by
Rectangles and Squares.

My problem with your proposal is not that it would not provide some useful
extention to current syntax.  My concern is that your solution only covers a
small subset of the problem domain, and as such must be considered a partial
feature, a potential source of more frustration than facility.
________________________________________________________________________________
Robert Reed			Home Animation Ltd.		503-656-8414
robert@slipknot.rain.com	5686 First Court, West Linn, OR 97068

We offer the party as a big tent.  How we do that within the platform, the
preamble to the platform, or whatnot, that remains to be seen.  But that
message will have to be articulated with great clarity.
--Dan Quayle, interview with the Washington Post, December 1989
________________________________________________________________________________
Newsgroups: comp.lang.c++