From: weide@elephant.cis.ohio-state.edu (Bruce Weide)
Subject: Re: OOD, Ada, and Inheritance
Organization: The Ohio State University Dept. of Computer and Info. Science
Date: Mon, 23 Nov 1992 20:10:13 GMT

In article <1992Nov20.202816.27409@beaver.cs.washington.edu>
chambers@cs.washington.edu writes:
>
>... I've forgotten the original question
>by now, but my response was providing a concrete example for dynamic
>binding and inclusion polymorphism as commonly found in OO languages.
>The alternative (at least in Ada) is quite painful.  In any case, I
>don't recall why you're interested in the restricted subcase of
>providing multiple implementations with *identical* abstract behavior.
>I'm sure it's less common and less useful than collections of
>implementations with related abstract behavior.  An example of
>multiple implementations with identical behavior is multiple
>implementations of a key-value table (lists of pairs or hash tables);
>both have the same abstract behavior but different performance
>tradeoffs for large and small tables.
>

I could not agree that having multiple implementations for the same
abstract behavior is "less common and less useful than collections of
implementations with related abstract behavior."  That this may be
less common (at least among OO enthusiasts :-) is not so debatable or
so important.  The more important question is what we SHOULD have.

There are two issues.  First, why do we want to have multiple
implementations for the same abstract behavior?  Performance
trade-offs, as Craig points out with a good example above.  Enough
said... except for the question of good examples where we want to
choose among these various implementations dynamically.  I can imagine
such, but they seem rather less plentiful than the number of
situations in which one might like to be able to choose performance
characteristics somewhat independently of abstract functionality, but
still at compile time.  If anyone has good examples for this dynamic
situation I'd be grateful.

Second, why do we NOT want to treat collections of classes/objects/
whatever exhibiting SIMILAR abstract behaviors, as though they were
just multiple implementations of "related abstract behavior"?  It's a
question of where you draw the line; what's similar and what isn't?
Oh, I know you can define this precisely in terms of language
mechanisms.  But what about MEANING?

To make this question more precise...  One of the main reasons for
abstraction is to provide an implementation-neutral explanation of how
a component is going to behave (functionally) in a client program --
precisely so the client does not have to examine the source code for
the implementation in order to know WHAT the component is going to do.
The client's going to have a hard time reasoning about his/her
program's behavior in this way if the ACTUAL ABSTRACT BEHAVIOR of the
component that is observable by the client differs (even slightly)
from one moment to the next during program execution, as different
implementations with "similar but not identical abstract behavior" are
invoked for the "same" operation.

Maybe this doesn't matter too much for "small" or "prototype"
software, but for industrial-strength software in life-critical
applications...  Well, I'm reminded of the line from Ghostbusters that
goes something like, "You don't often see behavior like that in a
major appliance."  Let's hope not.  But how is occasionally bizarre
behavior going to be avoided if our informal reasoning about client
program behavior is unsound and/or incomplete (in the logical sense)?
That's the inevitable consequence of saying that SOME (ANY) of the
abstract behavior exhibited by the dynamically chosen implementation
is not known until run-time.

So I now rephrase the original question: Can someone give me a good
example of a case where one wants to have multiple implementations for
SIMILAR but NOT IDENTICAL abstract behaviors, AND for which this
abstract behavior is specified formally and in implementation-neutral
terms (or at least could be in principle)?  Although I just argued
against this, I think there may be some (and I may even know some),
but I'm interested in what those in the OO community would consider
good examples of this situation.  As part of the example I would, of
course, expect to see the abstract specification of that part of their
behavior that these different implementations would all have in
common.

Cheers,
    -Bruce
Newsgroups: comp.lang.ada