From: ES
To: Editor
Date: 30 Jun 2004
I just (almost) finished reading AN INTRODUCTION TO DATABASE
SYSTEMS, 8th
Ed. And I have a bit of a problem with type inheritance. I would be
pleased if I could get some clarifications. I'll try and explain with an
example.
Let there be a type Ellipse as described in ch.20. Let there also be an operator STRETCH, that
multiplies THE_A (largest axis) by a certain factor f (where 0<f). Now, the implementor has deliberately chosen
to provide this operator for ellipses specifically, and thus NOT for
circles. The reasoning being somewhere
along the lines that it is indeed possible to "stretch" (c.q.
"shrink") an ellipse along its longitudinal axis, but that this is
not possible for circles, for then they would no longer be circles.
Now we have some programmer (user ?) who has developed a
program (procedure ?) with a variable of declared type Ellipse, that gets STRETCHed
a number of times during the proceedings (assuming that this user has a good
reason to do so - e.g. this user might be doing Monte Carlo simulations to
study whatever aspect of ellipses he finds interesting to study). Now note that it is perfectly possible that
this variable (with a value) of type Ellipse, can become a circle by
"stretching" it (with a factor f = b/a). Incidentally, this could be
an effect that is indeed (occasionally) desired, but it could equally well be
an undesired side-effect of some rounding error or so.
Now if I understood ch.20 correctly, then the system should
determine its "behavior" (which operators are available etc.), based
upon the VALUES within a variable and NOT based upon the declaration of that
variable. I found this explicitly
stated somewhere at the end of the chapter. (Incidentally : this implies that
the system must do some sort of "complete type hierarchy check" once
for each and every single assignment operation in a procedure/program -
hardware vendors will cheer. End of
aside). This in turn implies that, once
this variable has indeed become (to contain the value of) a circle, then the
STRETCH operator is no longer available (indeed, as stated elsewhere in ch.20,
the THE_A selector used by STRETCH is simply unavailable for circles), and the
program can therefore no longer proceed !!!
Of course, the solution at hand is to provide a circle
version of this STRETCH operator, that takes THE_R of the circle, and returns
an ellipse (value), so that we have again an ellipse to work with. But this implies that we are rewriting our
stretch operator, something that type inheritance aims to avoid in the first
place. And furthermore, this also
contradicts with the "semantics" of the operator as chosen in the
first place, namely that circles cannot be stretched. So what is happening then, is that operators are provided in order to circumvent certain undesired behaviors of the system, rather than based upon pure "semantics" (or "purely "). This just does not seem like the right way to go.
Furthermore, in the example given, it does not at all seem
unreasonable to assume that the user expectation would precisely be that the
variable RETAIN its "elliptic" characteristics, even after it has
("momentarily" or "accidentally") "become a circle". I believe that there is no general way of saying which of both "behaviors" (i.e. become a circle or remain an ellipse) will be desirable IN ALL CASES.
I am therefore more inclined to believe that (as you quote
some writers state) indeed there is no sensible "general mechanism of type
inheritance". And that any scheme worked out along the lines of an
inheritance mechanism, only works fine as long as any newly arising
requirements "coincide" (loosely speaking) with the mechanism that is
already in place. And that is, of
course, at the (huge) risk of being confronted with new requirements that
"coincide" only for about 50%, and then trying to force-fit the remaining
part into whatever seems least inappropriate.
C. J. Date Responds: I’m glad you've apparently
managed to struggle through the whole of AN INTRODUCTION TO DATABASE
SYSTEMS! You ask about type
inheritance.
If I understand your questions properly, they seem to be
based on a misconception. You say the
operator STRETCH is provided "for ellipses specifically, and thus NOT for
circles." First of all--in our
model of inheritance, at least--in order for the operator to apply to
"ellipses and not circles," it must be an update operator, not a
read-only operator. Second, to say it
applies to "ellipses and not circles" must mean, more precisely, that
it applies to variables of declared type ELLIPSE and not to variables of
declared type CIRCLE. Third, it's
important to understand that updating a variable E of declared type ELLIPSE
(via STRETCH or any other update operator) in such a way that the most specific
type of E becomes CIRCLE does not in any way affect the set of operators
that can legally be applied to E.
To spell the point out: The
operators (update or read-only) that can legally be used on a given
variable depend on the declared type of that variable, not its most
specific type. Thus, STRETCH in
particular can still be legally applied to E, even if E currently contains a
circle value. (Its effect might be to
cause E to contain a noncircle, of course.
Loosely speaking, STRETCH causes one ellipse to be replaced by
another--where either the "old" ellipse or the "new" one
might be a circle, because circles are ellipses.)
The real problem here, I suspect, is a confusion over values vs.
variables. You talk in terms of
"ellipses and circles." I
would like to recommend, politely, that you consider always using the explicit
terminology of ellipse values, circle values, ellipse variables, and circle
variables. Remarks like "this is
not possible for circles, for then they would no longer be circles" would
become so much clearer! A circle value
cannot be "stretched," because values can't be updated at all. An ellipse variable can be
"stretched" (meaning its old value is replaced by some new value),
and the result might indeed be that the ellipse variable now contains a
circle value--or that it used to contain a circle value but now
it contains a noncircle value. A
circle variable cannot be "stretched," however, because the
update operator STRETCH is not defined for variables of declared type
CIRCLE.
There might be a confusion over read-only vs.
operators, too. This logical difference
is tightly connected to that over values vs. variables.
Further points:
·
You say "this implies that the system must do some
sort of 'complete type hierarchy check' ... for each and every single
assignment." This claim is
incorrect. Hints as to why it's
incorrect appear in FOUNDATION
FOR FUTURE DATABASE SYSTEMS: THE THIRD MANIFESTO (2nd edition); a much
more detailed explanation will appear in the third edition, due from
Addison-Wesley next spring.
·
You say "the solution ... is to provide a circle
version of this STRETCH operator, that ... returns an ellipse
(value)." Now I'm confused. If it returns a value, it's a read-only
operator, not an update operator. But
if it's a read-only operator it already applies to circle values, and the whole
basis for your criticisms goes away.
·
You say that "to provide a circle version of [the]
STRETCH operator" implies that "we are rewriting our stretch
operator." Not so. If it's a read-only operator, the very same
implementation code will suffice. If
it's an update operator, the possibility of providing "a circle
version" doesn't arise (nor is it needed).
·
You say that to provide a circle version of STRETCH
contradicts the semantics of the operator.
No, it doesn't. Values vs.
variables!
·
You say "the user expectation would ... be that
the variable RETAIN its 'elliptic' characteristics, even after it has ...
'become a circle'." But it
does! Though once again I must point
out that the remark would be much less susceptible to misinterpretation if it
had been phrased in terms of values and variables. To repeat: A circle
(value) is an ellipse (value).
·
I reject your final paragraph. It turns out that we can use our
"pure" (?), "logically correct" (?) inheritance model to
achieve the effects some people want to achieve with their different
("impure"?) models--including what's often called "the extends
relationship." This is another
issue we will elaborate on in the 3rd edition of our MANIFESTO book. We stand by our claim that our model is a
useful, usable "general mechanism of type inheritance."
Posted
9/10/2004