Boost logo

Boost :

From: Gennaro Prota (gennaro_prota_at_[hidden])
Date: 2003-01-30 07:05:34


On Thu, 30 Jan 2003 11:13:23 +0100, Terje Slettebø
<tslettebo_at_[hidden]> wrote:

>>From: "Gennaro Prota" <gennaro_prota_at_[hidden]>
>
>> On Tue, 28 Jan 2003 10:47:52 -0800, "Andrei Alexandrescu"
>> <andrewalex_at_[hidden]> wrote:
>>
>> >"Peter Dimov" <pdimov_at_[hidden]> wrote in message
>> >> While we're at it, is the final verdict that is_base_and_derived<void,
>X>
>> >> should be false? What about is_base_and_derived<void, void>?
>> >
>> >Well, clearly void is no base. Even if we also define
>is_super_and_subtype,
>> >void is hardly a supertype of everything.
>>
>> Could you please clarify this? You mean:
>>
>> T is a subtype of U <=> ...?...
>>
>> T is a supertype of U <=> ...?...
>
>Supertype/subtype is a more general notion than inheritance and
>base/derived. The Liskov Substitution Principle states[...]

Be careful though. If you bring in a "behavioral" principle like LSP
than the issue becomes complicated. The square/rectangle example is
classic: if your square class throws e.g. when detecting that
invariants are broken then it's trivial to construct an object of type
square o1 and a program P defined in terms of rectangles which changes
behavior if you replace an instance of rectangle with o1. Whether
defining such a square class is good practice or not is another
matter. The point is that is_base_of is just a mechanical relation
that is difficult to define in terms of behavior. Putting it
differently, that's why inheritance can be misused in C++: it's up to
you to ensure a "match" between the substitutability definition and
the mechanical one. Roughly speaking B is a base of D if and only if
the base-specifier-list of D contains a class name for B or for a
class of which B is a base. Of course you can see if that's the case
by knowing the definition of D and examining an inheritance graph. And
since that's what a compiler does all the time, is_base_and_derived is
another thing that could be (ahehm) easily implemented as a built-in
operator. Not that I'm set for it, but please think about this: can
you give off-hand a proof that Rani's implementation is equivalent to
the mechanical definition I gave above? If you are going to write the
documentation for is_base_and_derived what do you write? The
definition above? Or something else? If you write the definition above
(as it is now, because the docs say more-or-less "if and only if B is
a base of D") shouldn't you prove that it is implementable in C++? How
much time will the committee spend to get agreement on the definition
and seeing that it is implementable? How much time does it take to
implement the built-in operator once you stick to the "mechanical"
definition? Maybe the answer to the last question is much much smaller
than the previous ones.

>>"What is wanted here is something like the following substitution property:
>If for each object o1 of type S there is an object o2 of type T such that
>for all programs P defined in terms of T, the behavior of P is unchanged
>when o1 is substituted for o2 then S is a subtype of T."
>
>Notice that it doesn't say anything about "class" or "inheritance",
>anywhere. If S = T, LSP still holds. Therefore, as Andrei said it, in
>language theory, such as this, a type may be considered its own
>supertype/subtype.

Actually the reason for my question is a little strange :-) I hope to
explain it in understandable English: Andrej said

    "void is hardly a supertype of everything"

Rewording it, it is: "void is not a supertype of everything".

This immediately made me think to why he didn't say: "not a supertype
of anything". In other words I wondered: "is he implying that void is
not a supertype of everything but *is* a supertype of something"? What
it this "something"? :-) That's an example of my odd mental
contortions.

>Supertype/subtype may also have other forms than inheritance. "short" may be
>considered a subtype of "int"

I don't know. The LSP definition seems to elementary to me to map to
C++. Think e.g. to binding an int to a reference to int&.

  int main() {
    int i;
    int & r = i;
  }

Can you replace "int i;" with "short i;"?

Genny.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk