Re: Clean Object Class Design -- Circle/Ellipse

From: Bob Badour <bbadour_at_golden.net>
Date: Fri, 31 Aug 2001 22:11:11 -0400
Message-ID: <NsXj7.612$ca4.124387451_at_radon.golden.net>


Dmitry Kazakov wrote in message <3b89f7a6.1013500_at_news.cis.dfn.de>...
>On Sun, 26 Aug 2001 16:14:13 -0400, "Bob Badour" <bbadour_at_golden.net>
>wrote:
>
>>>>>>>This definition of inheritance is in fact a LSP definition of a
>>>>>>>constrained subtype. If you define subtypes as LSP-subtypes, then
yes,
>>>>>>>you can design Ellipse, so that no Circle cannot be made its subtype.
>>>>>>
>>>>>>Have you considered that one must apply LSP separately to variables
and
>>>>>>values. Values do not change -- ever. Variables do change. This makes
>>them
>>>>>>very different things.
>>>>>
>>>>>Surely. It is what I call in-, out- and inout-subtyping.
>>>>>
>>>>>>A circle value is always an ellipse value.
>>>>>
>>>>>Never. A circle value has the type Circle.
>>>>
>>>>It's most-specific type is Circle. A circle value also has the type
>>Ellipse,
>>>>due to the subtype relationship.
>>>
>>>It seems that you are mixing class-wide and specific values.
>>
>>You've lost me here. What exactly am I mixing? A value is a value.
>
>Yes, and any value has a type.

Any value has multiple types: its most-specific type and all of its inherited types.

>>>Unfortunately most of OO languages do not differentiate them.
>>
>>Most OO languages do have the notion of a most-specific type, a declared
>>type and a general (polymorphic) type.
>
>Yes, but they do not differentiate specific and class-wide types.

You are again confusing things by introducing undefined, unecessary new terminology. "class-wide type" is meaningless.

"Most-specific type", 'declared type" and "inherited type" have meaning.

>C++ any value is considered depending on the context either as
>specific or as class-wide. A consequence of this is the necessity to
>always have type tag within the value.

You are talking about implementation-specific details that are ultimately irrelevant to the discussion of type and inheritance.

>With in turn (1) makes
>impossible to have dispatching methods for small objects (like bool,
>int, double etc.) (2) makes multiple dispatch hard to implement (3)
>makes multiple inheritance space consuming

None of this is relevant to a discussion of type inheritance; although, it might have practical implications for a specific implementation of C++.

>>>A specific Circle is not an instance of Ellipse. It is an instance of
>>>Circle.
>>
>>An instance is not a value -- it is a variable.
>
>No. An instance of a type is a value of that type.

Values do not change -- ever. Do instances? Instances are variables.

Consider: Values exist regardless of whether any representation currently exists for them in the universe. The value 5 exists even if it appears nowhere in your application or your computer at some point in time.

>A variable of some
>given type may hold values (instances) of that type.

This is a common misconception. A reference to a variable of some given type refers to a specific variable (instance) of that type.

An instance (variable) of some given type may hold values of that type.

Variables have identity. Instances have identity. Values are identity. (Values are self-identifying, if you prefer.)

One can have pointers to an instance. One can have pointers to a variable. One cannot have pointers to a value because self-identifying values exist independent of representation. (One can point to a representation of 5, but one cannot point to 5.)

>>I agree that Circle
>>variables are not Ellipse variables and vice-versa. The same is true of
any
>>subtype variable and supertype variable, which is why I think well-thought
>>languages must clearly distinguish between variable and value.
>
>They are well distinguished in any language.

If that is so, why does C++ have any difficulty implementing the very natural subtype/supertype relationship between circle and ellipse?

>More important is that
>one should distinguish between readonly (in) and full access (inout,
>out) variables.

I disagree. Constraints on variables are nowhere near as fundamentally important as a distinction between the very different concepts of value and variable.

>>>In contrary to this both a class-wide Circle and a class-wide
>>>Ellipse are instances of Ellipse'Class [not Ellipse!]. A class-wide
>>>value consists of the type tag indicating the type and the value of
>>>that type [In C++ the type tag is allways in the value, which leads to
>>>confusion].
>>
>>Values have no type tags -- they just are. All of the above are simply
>>implementation issues and are ultimately irrelevant to the discussion at
>>hand -- as is the rest of your example.
>
>Disagree. Values of class-wide types always have a tag associated with
>them.

Again, you are confusing things by introducing undefined, unecessary new terminology. "class-wide type" is meaningless.

The "tag" to which you refer is an implementation detail. Obviously, the DBMS must know both the type and the representation of that type in use at any given moment. Whether the DBMS implements this with a tag is irrelevant to the discussion of type inheritance.

>An representation issue is whether the
>tag is embedded in the value or not.

Physical independence requires that the representation be unimportant to the user, which makes it irrelevant to the discussion at hand.

>>Your example did nothing to address the statement that a circle value, no
>>matter the representation, is an ellipse. It has all the properties of an
>>ellipse.
>
>My point is that a circle value is not an ellipse. It mimics an
>ellipse, because there is a defined conversion to ellipse.

Your statement that a circle value is not an ellipse does not change the fact that it is. Conversion is unecessary.

>The
>presense of the conversion makes possible to call ellipse's methods on
>circles.

It was possible without the conversion in the first place.

>So one might imagine that circle is an ellipse.

One does not need to imagine.

>-1 is not
>double

I disagree. In a poorly designed language, it might not be. But -1 is a valid value for a double precision floating point number. -1 is a valid rational and real.

>yet fabs (-1) is legal.

I thought we were discussion object oriented languages.

Should we not discuss whether Abs(x) is legal or whether Magnitude(x) is legal instead? Why should we introduce type-specific names for the operation when we can assume polymorphism?

>>>>>When you
>>>>>pass a cricle to a method of Ellipse, there is always a conversion
>>>>>circle->ellipse [than could be null].
>>>>
>>>>This is not necessarily true and is ultimately an implementation issue.
>>>
>>>1. If you drop type conversions, you must obligatory have same
>>>representation for all subtypes of a base type.
>>
>>One must have at least one possible representation for every type, and one
>>can have several. This does not require any type conversion.
>
>It would be to complex to have several representation for a type.

Says you. The principle of physical independence requires it. Deal with it.

>How
>the compiler would distinguish them?

The DBMS knows and understands its internals. How would it not?

>If they are distinguishable, then
>why not to call them [sub]types?

If they are indistinguishable to the user, why not call them the same type?

>Different types?

Nope. Different representations of the same type. For instance, the DBMS might allow both cartesian and polar representations of complex numbers. The user should not have to care which representation any given variable stores at any given time. The operations and values are equivalent regardless of the representation used.

>So you naturally
>come a cristal clear idea: a value has a type.

Yes. Ane one naturally comes to the crystal clear idea that a type has multiple equivalent representations.

>A type has an
>implementation.

I disagree. It has multiple implementations. There are more than one way to skin a cat, after all.

>Multiple representations/implementations can be easily
>achived via subtyping.

At the cost of confusion and additional work for the user. We in the database world do not accept that cost.

>It is actually what subtyping is for. Isn't it?

No. Subtyping is for subtypes not equivalent representations of the same type.

>class Circle : public RosaElephant, public Ellipse {...}
>
>You cannot pass such circle to an ellipse method without conversion.

In the specific implementation of your compiler, perhaps, but that says nothing about subtypes and supertypes in general.

>>It could be done without any conversion at all. In fact, physical
>>independence almost requires it.
>
>This
>
>1. Exposes representation, because it requires that a subtype have
>same representation as the base.

No, it does not. It requires that the DBMS understand how to operate on different representations of the same type without conversion, and it requires that the DBMS understand how to operate on subtypes without conversion.

>2. Eliminates multiple inheritance.

Again, it does not. You are confusing unecessary implementation details with essential aspects of the problem. Received on Sat Sep 01 2001 - 04:11:11 CEST

Original text of this message