Loose type checking in E
Wed, 21 Oct 1998 07:48:30 -0400
I have been holding off on this whole inheritance discussion, but I'm
going to stick my oar in now. Hopefully just once, since I'm in the
middle of packing my house.
If we are going to argue for or against inheritance, we should argue
on the basis of merits as a language and/or programming facility, not
on the merits of a particular implementation. There are many possible
implementations, some slow, some fast. If the feature is no good it
doesn't matter how good the implementation is, so we should ask about
the feature first.
My experience with inheritance in languages like Smalltalk has been
generally positive. The absence of types sidesteps issues like
contravariance that are a nightmare to programmers, to compilers, and
to type checkers. Ultimately, the problem with issues like
contravariance is that there simply isn't a right answer.
My experience with inheritance in languages like C++ has been
altogether miserable. Strong typing and inheritance don't mix, and
the attempts to work around this that are forced onto the developers
just make it all worse. In practice, the C++ templates feature is
most commonly used as a workaround to the absence of useful
polymorphism in the language.
Finally, it seems to be about two orders of magnitude harder to design
objects for reuse (i.e. inheritable libraries) than to design ordinary
objects. We concluded in 1986 while doing the first product ever
coded in C++ that this would prove to be a big problem, and it has.
Bjarne, I, Andrew Koenig, Stan Lippman, and many others talked about
this quite a bit at the time without coming to any good resolutions.
Empirically, Perl has done better at this because it does not enforce
a particular choice of disciplining framework.
Inheritance vs. EROS:
People sometimes ask: is EROS object oriented? I no longer say
``yes'' to this question, because the term ``object oriented'' has
come to imply inheritance. EROS provides object encapsulation, which
is the real heart of object oriented systems, but it does not provide
In all of the cases we have found where inheritance like mechanisms
might have been appropriate, we have been able to resolve matters by
creating common protocols -- in E terms, common methods. Two objects
with nominally similar behavior respond to a common subset of order
codes (methods) with common behavior. Internally, they are free to
implement this by calling other objects, including a ``parent''
object, and they are free to export multiple interfaces.
I think these answers would apply equally to KeyKOS.
My preferences on what to do:
+ Something akin to the Java ``interface'' notion resolves most of
the places where I want inheritance even in a strongly typed
language, and solves it better than inheritance does. Such a
mechanism resolves several other issues as well.
Among other advantages, the interfaces approach makes the widening
effect of inheritance (see below) more explicit to the
+ After 20 years of object oriented programming, programmers can now
be said to understand the merits of common object behaviors.
Perhaps a language feature is no longer called for. A good
exemplar library of useful facilities may serve as a better guide
anyway, because it has social inertia.
As an author of one such library for C++, I'ld much prefer
interfaces to inheritance.
Summary: interfaces are better than inheritance. Inheritance is not
better than nothing.
> The root of the problem is that inheritance gives you more
> delegation than what you want. For even experienced programmers, it
> can be difficult to properly manage all of this hidden delegation.
I agree, but I think the word is 'impossible', not 'difficult'. In an
inheritance-oriented language, the superclass must export all of the
functionality required by all subclasses. From the perspective of any
particular subclass, this is too much. It is therefore possible in
principle to get this right only if the inheritance chain is linear
(i.e. not a tree), under which circumstances inheritance really isn't
> Moreover, inheritance encourages the designer to reuse by widening the
> interface of an object.
> Well, Mark decided to eliminate threading because he feels that
> despite familiarity, threads are a top source of headaches. I think
> I can make a convincing argument that more headaches have been
> caused by inheritance.
Applying the Uncle Joe Stalin test: :-)
If we took all of the people in Silicon Valley who have ever written
thread code out back and had them shot, we wouldn't notice any
reduction in population density in the valley. We *would* notice a
significant reduction in mean talent level. Most of the people who
write thread code are the very best in the business, because thread
code stuff is blasted complicated. Witness the many creative ways in
which the Java crew have screwed this particular pooch (I've noted
that my dogs don't care for coffee...).
I have heard it suggested that the real problem with inheritance is
that it encourages the great unwashed of programmers to play with
something that is blasted complicated, and we all then spend time
trying to repair the damage. I'm not sure I agree, but it's certainly
food for thought.