OOP

Nick Kallen phantom@earthlink.net
Mon, 10 Nov 1997 01:03:32 -0800


To some extent, I would like to remove former comments from the list. I
realize now, that with type classes and dynamic types, the effect of type
extensibility that I desire can be accomplished.
    My former problem is that I thought too much in terms of extensibility
as through -records- and not enough in terms of constructs that Clean
already implements. Let me explain by example.

class Drawable a
where
    draw :: a Picture -> Picture

instance Drawable Circle
where
    draw circle picture = DrawCircle circle.position circle.radius picture

DrawAll :: [Dynamic] Picture -> Picture | Drawable Dynamic
DrawAll [d:ds] pic = draw d (DrawAll ds pic)
DrawAll [] pic = pic

Thus you can see my whole request for extensible records was pretty narrow
minded, considering that what I want can be done without it. On the other
hand. my old request that type classes work with Dynamic types is still
emphatically supported. And I think the above example shows why they'd be so
damn useful.

Now, I realize that the above example might be incorrect, because I don't
use the Clean construct for dynamic types.
    Thus, I might have to define DrawAll like:

DrawAll :: [Dynamic] Picture -> Picture | Drawable Dynamic
DrawAll [(d :: _):ds] pic = draw d (DrawAll ds pic)
DrawAll [] pic = pic

Note the (d :: _) in the new DrawAll (and contrast it with the d in the old
definition). Since the type restriction "Drawable Dynamic" is specified, one
can be sure that draw is defined for any d--and thus we can dispose of
whatever type d is; hence (d :: _).

Now, if you want to talk about multiple inheritance, you just use more than
one type class in your class definition:

class DrawableAndErasable a | Drawable, Erasable a


Now, on another note, I still think the power of type classes should be
extended. For example, the Clean language report defines:

class + a
where
    (+) infixl 6:: a a -> a

This, unfortunatley, is not as restrictive as the definition of + should be.
The properties of commutativity (a+b=b+a) and associativity
((a+b)+c=a+(b+c)) among other things must hold.
    My friend, who is into specification languages like VDM says that "first
order logic is undecidable." Hence, the compiler can never be sure that the
above constraints are satisfied. I still think such specifications are
useful.
    On the other hand, the compiler/run time environment can assure -some-
constraints. I'll again explain what I mean by example.

class shortList a | length a
where
    length a <= 25

The syntax I'm using is pretty stupid in that I'm using a polymorphic type
variable as a parameter for a function. Regardless, I think the meaning is
quite obvious, and I can imagine that such constructs in the language could
be really useful.

Comments?