
The differences in the two shape examples doesn't have to do with code inheritance - it has to do with subtype polymorphism. Existential types allow you to throw different subtypes into a collection and have the function dispatch on the common superclass type. The example without existential types demonstrates parametric polymorphism, but not subclass polymorphism. Generally speaking, OO programming is based on three properties (a) encapsulation; (b) inheritance; and (c) polymorphism. Well, Haskell has pretty good means of encapsulation (though I'm spoiled by ML at the moment). And existential types can get you subtype polymorphism. As far as inheritance, there's actually two kinds that occur in most OO languages. The first being type inheritance (which really just gets you subtype polymorphism). And then there's code inheritance - which is what you are trying to achieve. A language like Sather actually treats type inheritance and code inheritance as seperate things. Languages that mix the two concepts have their own set of difficulties, as the two forms of inheritance are sometimes at odds with each other. Anyhow, the classic case for code inheritance is from a re-use perspective - i.e. not having to repeat the code in multiple places. The classic problem with code inheritance is that it breaks encapsulation, as classes that reuse code from a superclass become tightly coupled with the implementation. At any rate, I consider inheritance to be a convenience mechanism, and not vitally necessary to the concepts of encapsulation, type inheritance, and polymorphism, though I realize that many do consider it important. From a Java perspective, you usually have to decide whether you want single inheritance via class extension, or multiple inheritance via interface implementation.
From the perspective of Java, the shape example that does not have code inheritance corresponds to the Java world of Interfaces - with Interfaces not allowing code inheritance.
Chris Rathman
--- Cédric Paternotte 1. Through existential types As shown in the Shapes example at http://www.angelfire.com/tx4/cus/shapes/haskell.html. However, I couldn't
spot the advantage over the standard version using
normal classes at http://www.angelfire.com/tx4/cus/shapes/haskell98.html The getX function still needs to be defined in both RectangleInstance and CircleInstance.
This is not what I call inheritance. Inheritance
would make it possible
to define getX only once in ShapeInstance. Or
maybe the point was only
to demonstrate polymorphism. But then what is
the advantage of using existential
types ? It just looks like more
work compared to the standard version that
also makes use of
polymorphism. Or am I missing something ?