Re: Clean Object Class Design -- Circle/Ellipse

From: peter_douglass <baisly_at_gis.net>
Date: Sun, 19 Aug 2001 21:19:11 -0400
Message-ID: <3b8021ac_at_tobjects.newsource.com>


Responding to Marc Gluch:

[snip]

>>I really don't see this. I write a general math library, that works with
>>"real" numbers. Then I have occasion to deal with some quantities that I
>>wish to constrain to natural numbers. For example, number of items of a
>>given sort in a shopping basket. My contraint of holding number of items
 to
>>be a natural number is a data integrity constraint. We don't sell half
>>boxes of cereal, although we do sell bananas by the pound. The constraint
>>reduces the frequency of input errors. On the other hand, it is perfectly
>>legal for me to ask for the average number of boxes of cereal purchased
 per
>>customer per visit. I get a rational number (or a "real") as a result,
 but
>>I don't need to write a specific math library that deals with natural
>>numbers, I can "re-use" that. Isn't this "drawing beneifs from two types
>>being in the subtype relationship"?
 

>I would argue that it's a benefit of being in the subset relationship.
>But what exactly is this benefit? The only one that I can see is
>the ability to pass integers as arguments to real functions.
>You get neither specification nor code reuse (average number of boxes
>is code use, to get reuse you need to be able to compose
>real functions with integer functions).

Hmm. Integer and Real are different types, but using the same code for both is not code reuse. You apparently have a more restricted view of code reuse than I do. Can you give an example of this more restricted sort of code reuse?

>>Why do we need to forbid taking the multiplicative inverse of a non-zero
>>natural number? I would think we would want to do this, and often.
 Witness
>>average, which involves the multiplicative inverse of the cardinality of
 the
>>bag we are averaging.

>Because we can't construct a definition of integer avarage(integer i)
>that conforms to the invariants specified in the superclass.

Let me ask you. Does a subtype, in your opinion, need to be a subclass? I ask this because the sense that I'm getting of your objection to Date/Badour is that Integer should not be a subtype of Rational because one typically constructs rationals from integers rather than the other way round. I would argue that subclassing and subtyping are orthogonal issues, which unfortunately have been merged in most OO languages. IMO, there is nothing wrong with using the specification of integers as a basis for the specification of rationals, yet make Integer as subtype of Rational. Further, I think one should be able to declare a subtype relationship when there is no code inheritance one way or the other.

>>I made it harder than it needs to be ;-( Really though you are right.
>>Constructive math is often not trivial. On the other hand, it is free of
>>those nasty paradoxes that come about when you bind words to things you
>>can't construct. "Let R be the set of all sets that do not contain
>>themselves" might be valid English, but when the dust settles, we really
>>haven't bound anything meaningful to "R".

>Actually, that's what led to type theory (although Russell may have
>used the word class in Principia Mathematica). My original reference
>to Martin-Lof was not to point out his definition of subtype (since
>the article was about the monomorphic TT), but rather to rebut Badour
>and others equating types with sets.

I'm not sure you still hold to this position given that Badour has recently explained that for Date and himself, a type is a set of values and a set of operations.

>>>I believe your definition reduces to Date's.

>>Perhaps. I'm not sure though.

>Your proof is based on the idea that A implies B, if A is a subset
>of B (through some function mapping A to B). That's why I think is
>equivalent to Date's.

>>Consider the set of total functions from
>>{1,2,3} to {4,5}.

[meant to say {4,5,6} here, but it doesn't change the argument]

>> Call it F. If I have some way to determine whether a
>>function is defined over the set{1,2,3} and its image is a subset of
>>{4,5,6}, and I further have some way to determine whether two functions
>>yield the same results when applied to the values within the domain
 {1,2,3}
>>then I can asssert that F is a Martin-Lof type (per the paper I cited).
 Now
>>if I have another set of total functions from {0,1,2,3} to {4,5}, call it
 G,
>>then I think I can assert under my speculative version of Martin-Lof's
>>theory that G is a subtype of F.

>Are you sure you didn't mean that F is a subtype of G?

My mind may be playing tricks on me, but I think I have this right. If I have a proof that some function f has type G, then I have a proof that f is defined over the set {0,1,2,3} and its image over that set is a subset of {4,5}. From this I can construct a proof that f is defined over the set {1,2,3} and its image over that set is a subset of {4,5,6}. Thus, f is also of type F. Since "f is of type G" implies "f is of type F" for any f, G is a subtype of F.

>> I'm not sure this is true of Date's
>>theory, but again, I'm lacking sources at the moment, so it is just a
guess.

From Badour's comments, I see that I was wrong. Date's theory and Martin-Lof's are very similar.

[snip]

>>> You can prove that
>>>Integers are a subset of Rationals, but the utility of that proof is
>>>limited, since you can't pass integer parameters to rational functions
>>>and expect an integer result.
 

>>There is no reason why I would expect that I would always get an integer
>>result. I can use rational numbers as arguments to transcendental
>>functions, and get transcendental results. What I fail to see is why
>>yourself, and some other posters, find it so important that the result
 type
>>change (covariantly) with changes in the argument types.
>What I consider important is not result type change, but rather
> preservation of meaning (commutativity of composition and
> interpretation).
 

>>You don't seem to value sub-sets as being sub-types.
>> I'm not sure why. For me, a key value
>>of types is the ability to include specification information within a
>>program, and to have the type-checker reject programs for which the
 included
>>type specifications do not match the program functionality.

>But what kind of specification are you talking about?
>Signatures, or axiomatizations (invariants)?

signatures

>>Types used in this way are just useful decoration of programs,
>> and may be erased without altering the semantics of the program,
>>which could otherwise be written in an untyped language.

>That's why I think that there is little value to this definition of
>subtype. I have to declare all types, indicate how they relate to
>others, and all I get in return is a (potential) reprimand that
>some of my usage is not "safe". No code reuse.
>It would be much more useful if the compiler could look at two
> specifications and determine if they are consistent, but that is not
>realistic.

Sorry you see little value in the compiler warning you that your declarations and usage don't match. However, others do, so your claim that declaring subsets as subtypes is useless is debatable.

[snip]

--PeterD Received on Mon Aug 20 2001 - 03:19:11 CEST

Original text of this message