Henry Spencer <henry@zoo.toronto.edu> wrote:>Indeed, there are a significant number of people who think that once you>strip away the OOH (Object-Oriented Hype), being able to reuse>*interfaces* is much more important than being able to reuse code. If the>interface is held constant, you can build up a library of different>implementations of the underlying abstraction to satisfy different sets of>tradeoffs.

Steven D. Majewski <sdm7g@elvis.med.virginia.edu> writes:>From my recent experience with using classes in Python, I would agree with>that statement. Python is an OO language that is "objects all the way>down", but the builtin objects are not part of the class system.

This is a little off thread, but it does point out a very common mistake
made in discussions of things object-oriented.

To say that "X is an OO language with objects all the way down" *means*
that in X, everything is an object. If X has a class system, then
*everything* is in the class system. To say that "X is an OO language with
objects all the way down, but the builtin objects are not part of the
class system" is much like saying "Y is a completely side effect free
language, except for the assignment statements."

... Thus,>you can use (multiple) inheritance with user defined classes, but you>can't inherit methods from builtin objects like files, integers, lists,>strings, etc. What you can do, though, is to emulate the interface of>builtin objects by defining the appropriate methods in your class.
...>For example, if you define methods for all of the standard numeric>operations, you can create new numeric types. If you define methods for>len, getitem, getslice you have something that behaves like a sequence,>and if you add setitem and setslice it becomes a mutable sequence.

In Sather 1.0, a new object-oriented language, you can do similar things,
by taking advantage of its two-part inheritance system. The idea is that
there are really two different kinds of inheritance - inheritance of
interface, and inheritance of implementation. In Sather, those two have
been separated into two different constructs in the language.

If you have a type that you want to use as a mutable sequence, you have it
inherit interface from the abstract type $MUTABLE_SEQUENCE, and then
provide implementations for all of the operations that work on a mutable
sequence:

In this case, you don't get any implementations that went with
NewSequence.

Alternately, you can reuse implementations by using implementation
inheritance, but without necessarily inheriting interface. So, for
example, you may want to implement a stack using the concrete
implementation of lists as a base. But a stack doesn't implement list
operations. So, you'd use implementation inheritance without interface
inheritance:

class Stack{T} is
include CONCRETE_LIST{T}
push(x:T) is ... end
pop:T is ... end
end -- Stack{T}

And, of course, you can inherit interface AND implementation by using both
inherit forms.

When I first read about this separation, I was very hesitant to accept the
intelligence of it. But on further consideration, especially in light of
the discussion here, it seems to look better and better.

It seems far better to provide something like this, which allows the use
of interfaces for static type-checking, but while also allowing the
programmer to disregard the internal structure and implementations of it
parent classes, is *far* more useful than the more restricted kind of
inheritance that has come before, and also preferable to the
Python/Objective-C kind of inheritance where similar effects are possible,
but without static type checking.

Anyone interested in Sather based on this should take a look at
comp.lang.sather, or at the language spec on icsi.berkelet.edu:pub/sather