The Third Manifesto

Question on Inheritance of Update Operators

TTM home

The following question, from Mark Friedenbach on 30 May, 2005, is one that has been posed, one way or another, by several correspondents.  It was actually addressed to Chris Date, for reasons that will become immediately apparent.

In Section 20.8 of  "An Introduction to Database Systems, 8th Ed." you argue that "inheritance of update operators has to be conditional; in fact precisely which update operators are inherited must be specified explicitly." I disagree. I've worked the examples that you presented myself and do not believe this restriction follows logically from the type inheritance model you describe.

The example you give in your book is that of a circle and an ellipse, where the circle is a constrained form of an ellipse

TYPE ELLIPSE
POSSREP { A LENGTH, B LENGTH, CTR POINT
                     CONSTRAINT A >= B } ;

TYPE CIRCLE
IS ELLIPSE
CONSTRAINT THE_A ( ELLIPSE ) = THE_B ( ELLIPSE )
POSSREP { R = THE_A ( ELLIPSE ),
                    CTR = THE_CTR ( ELLIPSE ) } ;

E := ELLIPSE ( LENGTH ( 5.0 ), LENGTH ( 3.0 ),
                         POINT ( 0.0, 0.0 ) ) ;

C := CIRCLE ( LENGTH ( 5.0 ), POINT ( 0.0, 0.0 ) ) ;

The problem you demonstrate is that [assignments to THE_A and THE_B of] the circle variable C cannot be used without violating the constraint which makes C a circle, e.g.

THE_A ( E ) := LENGTH ( 6.0 ) ; // okay
THE_A ( C ) := LENGTH ( 6.0 ) ; // fail, violates constraint A = B

Your solution is to restrict subtypes from inheriting update operators (or at least inheriting some update operators). In this case it would be illegal to use [assignment on THE_A and THE_B of] the variable C.

I find this decision arbitrary and unnecessary. Your primary justification was the dilemma in which "if circles inherit the operators 'assignment to THE_A and THE_B' from ellipses, then we get noncircular circles" (speaking loosely) on pg. 633. But this is not always the case, particularly if we admit the possibility of multiple assignment statements, e.g.

THE_A ( C ) := LENGTH ( 5.0 ) ;

THE_A ( C ) := LENGTH ( 6.0 ),
THE_B ( C ) := LENGTH ( 6.0 ) ;

Both these statements leave value of C as a perfectly circular circle. In the first case this is because THE_A(C) is assigned the value it currently holds, and in the second case because after the assignment the constraint for circles that A = B still holds.

At this point a better statement of the problem would be that the update operators THE_A and THE_B have the possibility of assigning a circle which is noncircular. However this problem is not original; consider the following update operations (assuming the initial values assigned above)

THE_A ( E ) := LENGTH ( 1.0 ) ;
THE_B ( E ) := LENGTH ( 9.0 ) ;

These updates assign a value to E for which THE_A(E) is less than THE_B(E). This violates the constraint we set on ellipses whereby A>= B must always hold. Thus even for ellipses THE_A and THE_B have the possibility of assigning an ellipse which is nonelliptical. Indeed, any time we introduce a type constraint we also introduce the possibility that the THE_* update operators may be used to assign an invalid value to a variable of that type.

With this in mind, it seems arbitrary to restrict the availability of any elliptical update operators for circles on the basis of noncircular circles when those very operators can be responsible for nonelliptical ellipses. The only solution I see is to signal a run time error if the most specific type of the value being assigned in an update operation is not a subset of the variable's declared type. This approach would cover both the cases of noncircular circles and nonelliptical ellipses, as well as free ourselves from arbitrary restriction on the inheritance of update operators.

I hope you can find the time to reply; I am very interested to read your thoughts on the issue. I agreed wholeheartedly with your treatment of type inheritance, with the exception of this one point.

Hugh Darwen replied (30 May, 2005):

Personally, I find your observations interesting, especially where you show how multiple assignment can sometimes be used effectively.

You clearly understand that our model of type inheritance does not prohibit inheritance of update operators. It just does not unconditionally require it. The formal definition of our model is given in "Foundation for Future Database Systems: The Third Manifesto", 2nd edition, by C.J. Date and myself, Addison-Wesley, 2000, 3rd edition to appear, 2005.) The formal prescription on update operator inheritance (page 254, numbered paragraph 19) states, after some preamble:

"It follows that, for each such update operator Op and for each parameter P to Op that is subject to update, it shall be necessary to state explicitly for which subtypes of the declared type T of parameter P operator Op shall be inherited ... (And if update operator Op is not inherited in this way by type T' [a subtype of T], it shall not be inherited by any subtype of T'.)"

The numbered paragraph is in fact "Inheritance Model Prescription 19". The prescriptions constituting our inheritance model are discussed in Chapter 14, where this one is given the title "Update Operator Inheritance and Variable Substitutability". The discussion of the application of this Prescription to our running example of ellipses and circles makes it clear that the type definer might decide that assignment to THE_A and THE_B of variables of declared type CIRCLE are to be prohibited.

Now, you use our same example to argue that it is possible for assignments to THE_A and THE_B to be supported for variables of type CIRCLE. I agree. You also claim that it seems arbitrary for those assignments not to be supported, given that if they were supported, then the run-time errors they would be subject to are similar in kind to the run-time errors that can occur even for variables of type ELLIPSE (in general, variables of the same declared type as the corresponding parameter of the update operator in question). Let's assume that I agree with that, too. Do I then have to agree that it is compulsory for the definition of every type T' to support all the update operators defined for variables of declared type T? I don't think so.

That said, I might very well agree that "this restriction [does not follow] logically from the type inheritance model [we] describe". (By "restriction" here, you mean restrictions that our model permits type definers to impose if they wish to do so. The Prescription that gives this permission is not of itself a restriction, of course--quite the opposite!) While we do firmly believe that logical consequences must influence language design strongly, we do also believe that some psychological factors need to be taken into consideration. Here we are talking about a psychological factor, not a logical consequence. We saw no compelling need to follow the typical object-oriented model in categorically requiring every update operator to be inherited. By contrast, we consider the requirement for all read-only operators to be inherited to be very much a logical consequence of our model.

A language that enforces update operator inheritance and conforms to every other Prescription of our model would, I suppose, have to be deemed strictly non-conforming to our inheritance model. However, a language that conforms fully would not prevent its users from adhering to a self-imposed discipline of universal update operator inheritance, if required.

I assume that you think we should take a more dictatorial approach, as indeed we do in The Third Manifesto itself as far as adherence to the relational model of data (and accepting all its logical consequences) is concerned. But you don't actually give any justification for such a dictatorial approach. (Please note that "The Third Manifesto itself" does not require type inheritance to be supported. Our inheritance proposals are separate from The Third Manifesto, which merely states that if inheritance is supported at all, then it should be according to this model.)

By the way, did you consider the extreme case of an update operator that never fails for variables of type T but always fails for variables of type T'? For example, the operator "add 1 to" always succeeds on variables of type INTEGER (well, with a single exception, of course, given that all types are finite), but always fails on variables of type EVEN_INTEGER. It seems reasonable to me to allow the definer of EVEN_INTEGER to make "add 1 to" a syntax error when invoked on variables of that type.

Mark Friedenbach (02 June, 2005):

While I would still maintain that the prescription you quoted from The Third Manifesto is not 'necessary' (to use your wording)--in that it is not required for your model of type inheritance to work correctly--your example shows clearly how such a facility is desirable. I agree now that restriction of the inheritance of update operators is a useful part of the model, even if CIRCLE and ELLIPSE do not provide the best example.

TTM home

© Hugh Darwen 2005

Date last modified: 02 June, 2005