Re: Clean Object Class Design -- Circle/Ellipse

From: Dmitry A. Kazakov <dmitry_at_elros.cbb-automation.de>
Date: Tue, 04 Sep 2001 17:24:10 GMT
Message-ID: <3b94d133.1837081_at_news.cis.dfn.de>


On Tue, 4 Sep 2001 03:14:31 -0400, "Bob Badour" <bbadour_at_golden.net> wrote:

>>>If we accept your assumption that no such thing as subtype exists, we can
>>>end this conversation now. The conversation is, after all, a discussion of
>>>subtype.
>>
>>How the view that any value has a type disallows subtypes?
>
>The view that any value has one and only one type disallows inherited type,
>which then disallows supertypes and subtypes.
>
>Any value has a specific type and possibly many inherited supertypes.

That a type inherits means only that methods are inherited. It can be well done for different types. For any method of the base type T f, there is a corresponding method f' defined for the subtype S. This means that S inherits f from T.

>If one properly recognizes the type difference between variables and values,
>LSP poses no problem. A variable is a reference to a representation of a
>value, which makes its type different from that of the value whose
>representation it references.

How it helps in the case of LSP. What happens when a variable of the type Circle is resized as if it were an Ellipse?

>>>This is not the accepted use of the term "class" in OO. The ISO standard
>>>vocabulary for programming languages equates "class" with data type.
>>
>>Nice to have several words for same thing ...
>
>The ISO standard vocabulary definition for "class" simply recognizes that
>the OO crowd invented a new word for an old concept.
>
>Your additional definition for "class" overloads the term with a confusing
>new meaning. I suggest we stick with one meaning, and I further suggest we
>stick with the general meaning used by OO practitioners.

The term class of types had existed long before. It is not my invention. However, feel free to give another word for the closure of subtypes.

>>>>>"Most-specific type", 'declared type" and "inherited type" have meaning.
>>>>
>>>>How many types has the value 1, provided that I can derive from
>>>>integer?
>>>
>>>Integer is rational is real is complex.
>>
>>So only 4 types. What if I derive my own type? What if I call my
>>friends to derive a bit more types?
>>
>>>Natural is whole is integer.
>>>
>>>Any others you would like to propose?
>>
>>Lots. The file descriptor for instance. 1 is stdout.
>
>File descriptor is neither a subtype nor a supertype of integer. While it
>uses similar symbols, the properties of a file descriptor, including defined
>operations, are neither a subset nor a superset of the properties of
>integer.

Did I claim that file descriptor is a subtype of integer? I said only that it has the literal 1. Which means that there are two different 1s.

>For instance, what does it mean to add two file descriptors?
>Substract? Multiply?

They have no meaning, they are operations of some other unrelated types. But nothing prevents me from making it a subtype of integer, so that 1 + 1 be 2 = stderr. Of course if your platonic approach is applied consequently one should think that there is only one + in the universe. But it is obviously wrong.

>Again, I must point out that your example uses an artifact from a non-object
>oriented system.

Maybe the artifact is that a particular system is unable to explain what appears "artefact"? I wouldn't blaim OO for this.

>>Literal can be viewed as a read-only variable. Both literals and
>>constants might require elaboration (construction) if they have some
>>complex types.
>
>This describes exactly why neither literals nor named constants are values!
>They are variables constrained to a single value.

Yes and this supports my view that values do not exist without variables.

>>Value of an ellipse cannot be resized because the result [in most
>>cases] is another value.
>
>One cannot resize an ellipse value because values do not change -- ever. One
>can resize an ellipse variable because variables do change.

"Resize" means "to call a routine named Resize with an actual parameter which value is of ellipse type".

>>Surely there would be no problem with LSP if
>>all operations violating it are removed.
>
>We have no need to remove any operations. We need only properly recognize
>the type of values. The type of a variable is a reference to the
>representation of a value, and the type of the variable is different from
>the type of the value.
>
>Operations like setFoci operate on variables and not on values.

Is "the type of a variable referencing a circle" a subtype of "the type of a variable referencing an ellipse"? Are they same types? On which type setFoci is defined? Does it violate LSP?

>>>>You pointed the distinction: values are immaterial and enjoy
>>>>witnessing of the God of programming. Variables are sinful and
>>>>condemned forever. (:-)) Seriously why in your opinion, say in C++,
>>>>values and variables are not distinguished?
>>>
>>>Update operations necessarily operate only on variables while non-update
>>>operations necessarily operate only on values, and C++ makes no
>distinction
>>>between the two. Constraining a variable to a single value or a subset of
>>>values is a different matter.
>>
>>1. Both update and non-update operations operate on variables
>
>...in C++... which is why I say that C++ makes insufficient distinction
>between variable and value.

Is there values in C++?

>>2. void Foo (const X); is Foo an undate or non-update operation?
>
>...in C++... it is impossible to say, because C++ makes insufficient
>distinction between variable and value:
>
>1. Foo could update a global or static variable.
>2. Foo could be a member function that updates the variable referenced by
>"this".
>3. Foo could be a non-update operation, in which case it performs little of
>enduring use.

From this point of view there is no non-update operations, because any operation always has side effects [memory mapping, stack use etc]. Some side effects are irrelevant to the currently used abstraction. So the property "to be update" is relative not absolute. Then Foo is non-update relatively to its first parameter.

>>There is no dynamic polymorphism without tags. So being non-existing
>>it would not work, which should wake up some interest of the user.
>
>Try to think out of the box a little. It is possible -- you just haven't
>imagined all of the possibilities.

Which ones?

>>Very convincing. Give your proof that in a language we both know one
>>cannot distinguish values of the base type from the values of one of
>>its subtypes.
>
>One can always determine whether a subset contains a given value.

"To determine whether a subset contains a given value" = to determine whether a value belongs to the domain of a type = to determine the type of a value, ... not knowing the type of that value! If we put aside the theory of divine influence then there is nothing that can help us.

>This does
>not prove whether a conversion is necessary as you claimed. Since a subtype
>value is also a supertype value, the DBMS can operate on it as the supertype
>without conversion.

This proves that to do something with a value you shall know its type.

>>>In my language, -1 is a literal of real type also.
>>
>>Then they are two different literals overloaded in some given context.
>
>Nope. A single literal has multiple types.
>
>>One -1 has the type Integer another -1 is Real.
>
>Nope. The single literal has both type Integer and type Real.

Now please, explain this:

type MyInteger is new Integer;
A : Integer := -1; -- Literal of what?
B : MyInteger := -1; -- Literal of what? B:=A; -- Compilation error - why?

>>>>>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?
>>>>
>>>>fabs is not polymorphic [unfortunately it is impossible in C++].
>>>
>>>fabs is not object oriented -- it exists in C, which says nothing about
>>>C++ and nothing about the topic of discussion.
>>
>>How a routine can be object oriented or not? Isn't it a property of a
>>programming language?
>
>If one assumes that the scope of object orientation is limited to
>programming languages, then anything discussed about object orientation is a
>property of a programming language. Some people have proposed extending the
>scope of object orientation beyond programming hoping to apply it to
>database management.
>
>In either case, discussing a function from a non-object oriented language
>like C says nothing about object orientation.

As far as I know the discussion was about C/E problem and subtypes. Should your statement mean that any non-polymorphic subroutine is not an issue regarding LSP and subtyping. What makes you think so:

  1. Non-polymorphic subroutines do not exist
  2. Non-polymorphic subroutines cannot be inherited
  3. Non-polymorphic subroutines never violate LSP
  4. Non-polymorphic subroutines always violate LSP

1-4 are wrong. Something else?

>I see where the confusion comes in. ISO equates "internal level" with
>physical representation of information. Type and representation are both
>metadata, and the DBMS must internally represent the metadata information
>somehow.
>
>In a DBMS, we have a physical design separate from a logical design and
>separate from dbms internals. A physical design could involve multiple
>possible representations for a given type. For instance, one can represent
>complex numbers in cartesian or polar coordinates. Both physical
>representations represent the same type, and the DBMS can use either
>representation interchangeably without any logical consequences to the user.

Now consider that the union of all that possible "representations" is also a representation, which never changes.

>The cartesian representation has derived properties for magnitude and angle,
>while the polar representation has derived properties for real and imaginary
>parts.
>
>A DBA would interact with and manipulate the physical design without always
>requiring detailed knowledge of internals -- just as a casual user would
>interact with the logical design without requiring knowledge of the physical
>design.

It just one of possible solutions in which both cartesian and polar view on the complex numbers are implemented using one type and one representation [which has some identification of the current view].

>>So I made the conclusion you argued that the
>>representation determines the type. Or it is the type that determines
>>the representation. In any case, to distinguish types by
>>representation there should be a mapping representation->type. This
>>excludes multiple type representations.
>
>Type does not determine representation. Physical representation does not
>determine type. Internally, the dbms must represent the metadata information
>regarding type and representation, but does not expose this internal
>representation to any user. This allows multiple representations for the
>same type.

It is exposed in dispatch.

>>>I can accept that provided we accept that representation is orthogonal to
>>>type.
>>
>>It is, in the sense that a user/compiler is free to choose a
>>representation for a type. But the choice shall be made.
>
>You assume that a single choice will be made, but the assumption is false.
>In order to provide physical independence, the dbms must allow multiple
>representations for a type.

Which union is the actual and single representation of the type.

>>Value is a language term here.
>
>What language? What is wrong with the generally accepted definition? How
>does the definition as a "language term" differ?

Values in a language are not mathematical objects they might occasionaly represent.

>>>Not my point. My point is: Type does not determine representation and
>>>representation does not determine type.
>>
>>Then you should explain how dispatch can work, if there is not way to
>>determine the type.
>
>Dispatch is ultimately an irrelevant implementation detail when discussing
>logical type inheritance. A DBMS might derive the type any number of ways
>just as it might derive the representation any number of ways.

Dispatch = [run-time] selection of an implementation of some polymorphic subprogram. Provided that implementations are written by the user, how could it be irrelevant which one is selected?

>>>Your example does not achieve the desired result. Complex is a single type
>>>regardless of the physical representation.
>>
>>Why? I can use both different complex types interchangeable. It is all
>>that we need, or?
>
>We need a single type. The user must be able to declare variables just by
>specifying Complex. The user must be able to discover the defined properties
>and operations from the system catalog by specifying a single type, Complex.

I prefer a system where the user can choose. It is very doubtful that whether to declare a variable DenseMatrix or SparseMatrix is irrelevant if the matrix is 100,000x100,000. It is also thinkable to have some IntelligentMatrix which would try automatically get an advantage from the distribution of non-zero elements, but in any case those three are different types.

>>A value having one representation can be converted to the value having
>>another representation. It does not make the types of those values
>>same.
>
>The abstract or logical interface determines type -- not the physical
>representation. One can convert from one representation to another without
>changing type.
>
>>It only establish a subtype relation between them.
>
>No subtype relationship exists because they are the same type.

[Subtype relation is reflexive]

>They have exactly the same values and exactly the same properties, including
>operations.

Do you really believe that (int) 1 and (double) 1.0 have same properties?

>>>>How do I distinguish that representations?

[...]

>>But DBMS knows and distinguishes that represenations?
>
>Internally, yes, it must.

[...]

>>>>And how do you call the set of all values having exactly one [of that
>>>>multiple] representation. I would call it a type. And you?
>>>
>>>I call it the empty set. All of the values have both representations.
>>
>>Simultaneously? So the representations are undistinguishable = same.
>
>Yes. At the logical level, the cartesian representation of Complex(0,1) is
>indistinguishable from polar representation of Complex(1,Degrees(90)).

Which means that there is exactly one representation.

What cannot be observed does not exist.

>>>>My proposal to you is
>>>>to consider the following naming convention (used in Ada). What you
>>>>call "type" [with multiple representations] is a class-wide type. What
>>>>you have no name for, is a normal type.
>>>
>>>My proposal to you is to consider the generally accepted naming
>>>conventions. What you call a "class-wide type" is the set of specific types that a
>>>variable of a declared type can contain -- either directly or through
>>>inheritance.

[..]

>>>What you claim I have no name for is an abstract data type. (See ISO/IEC
>>>2382-15.04.02)
>>
>>Sorry, but abstact types have no values => representation.
>
>Sorry, but the definition for abstract data type only requires us to
>describe the interface separately from the physical representation. It does
>not require abstract data types to have no representation. (See ISO/IEC
>2382-15.04.02)

"An abstract type is a tagged type intended to use as a parent type for type extensions, but which is not allowed to have objects of its own".

I meant the types that are allowed to have objects and those are not subject of dispatch. Such types cannot be equated to a set of types. In some particular language [which I wouldn't like to use] they can be made abstract to avoid having objects of that types.

>>>>>>It is actually what subtyping is for. Isn't it?
>>>>>
>>>>>No. Subtyping is for subtypes not equivalent representations of the same
>>>>>type.
>>>>
>>>>Equivalent in what sense. You claimed that representation is not an
>>>>issue for types [I completely agree with that], hence for subtypes
>>>>too. Whether a type is a subtype shall be representation-independed.
>>>
>>>A complex number with cartesian representation (0,1) is eqivalent to and
>>>equal to a complex number with polar coordinates (1,Degrees(90)).
>>
>>For any value of ComplexCartesian and any value of ComplexPolar there
>>are corresponding complex numbers. For some values they are the same
>>number. So what?
>
>All values have equivalent representations in both cartesian and polar
>coordinates.

No, the corresponding numbers [being same] have equivalent [same] representations in ...

>>>>>>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.
>>>>
>>>>In which compiler it could be possible?
>>>
>>>In any compiler that fully supports polymorphism.
>>
>>How it supposed to work, provided that according to you values of
>>Circle are values of RosaElephant and simultaneously of Ellipse?
>
>Why would it not work? Variables of RosaElephant can have any value of
>Circle as well as any other value of RosaElephant. Variables of Ellipse can
>have any value of Circle as well as any other value of Ellipse. Variables of
>Circle can have any value of Circle.

Because in this case the domain sets of RosaElephant and Ellipse would intersect. But RosaElephant has no axis, it has a big salivous trunk and a rose-colored bow with "Rosa" written upon it. You could try to resize it, but it will surely take offence.

>>>>>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.
>>>>
>>>>Let it understand, but how it could operate?
>>>
>>>Using operations. What makes you think it could not?
>>
>>It sees values and all those values are same. Which operation should
>>it use?
>
>It should use the operation whose parameters most closely match the specific
>types of its arguments.

So the type information is a part of the value. Here we go again...

Regards,
Dmitry Kazakov Received on Tue Sep 04 2001 - 19:24:10 CEST

Original text of this message