[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Curl, multiple inheritance, and interfaces (was Re: cheerful static typing)

Christopher Barber wrote:
> Curl does require that abstract classes be explicitly marked but does not
> require abstract classes to only contain abstract methods.

That's pretty standard.  You're right that for proper interface support, a
stricter construct is needed, other than abstract classes.

> We have
> considered having a stricter version of this, but felt that it was not
> useful enough to add to the language.

Not useful enough?!? ;o)  I think I've already made my own position clear,
but I'd like to add to it: if you think about it, an interface or contract
(or whatever you choose to call it, possibly including 'type') is one of the
most fundamental constructs in any programming language.  Even languages
that don't have objects implicitly use interfaces - integers have an
interface, for example.  A language like Smalltalk, which is not statically
typed, relies implicitly on interfaces, often independently of its class
inheritance - they're just not explicitly declared.

In fact, the other day Shriram mentioned about "dynamic dispatch" being the
main benefit of OO.  He didn't expand on that much, as I recall, but one of
the ways a language like Smalltalk uses dynamic dispatch is to support
implicit interfaces, unrelated to inheritance.  This allows objects
unrelated by inheritance to respond to common messages.  But given an
explicit interface mechanism, the same effect as dynamic dispatch can be
achieved, without actually requiring dynamic dispatch.  Of course, you than
have to statically declare your types (interfaces), which Smalltalk doesn't

[There's another use of dynamic dispatch, which is sending arbitrary
messages to arbitrary objects at runtime - "apply"- or "send"-like
functionality.  A static interface approach doesn't offer this capability in
itself - the ability to implement it depends on the amount of runtime
metadata available.]

> If we were to add a concept of an "interface", I would want it to be
> divorced from class inheritance, so that an interface would be compatible
> with any object that satisfies it.

That's the general idea.  This is allowed by what I was suggesting regarding
simulating interface behavior with MI, as long as each class that intends to
satisfy an interface explicitly declares that it does so - in the case of
MI, by inheriting from the abstract class which defines the interface.  The
fact that inheritance is used, to describe to the language that an object
supports an interface, doesn't really restrict anything - unless you
consider it important not to have to declare that a class supports a
particular interface, for some reason.  However:

>    {define-interface Lockable
>       {method {lock}:void}
>       {method {unlock}:void}
>    }
> and the class:
>    {define-class Mutex
>        ...
>        {method {lock}:void}
>        {method {unlock}:void}
>    }
> you could write:
>    {define-proc {lock l:Lockable}:void
>        {l.lock}
>    }
>    ...
>    let my-lock:Mutex = {Mutex}
>    {lock my-lock}

It seems reasonable - and actually quite important - to require a
declaration more like:

>    {define-class Mutex implements Lockable

If you're suggesting that simply because a class happens to include methods
that match a particular interface, that it should satisfy that interface, I
don't think that's a very good idea.  It is what Smalltalk-like languages
effectively do, though, but that's only because they're not being explicit
about interfaces at all, and because they only support single inheritance so
are forced to "cheat" to support multiple interfaces on an object.

> This is an improvement over use of 'any' in that use of the
> interface could be checked at compile time.

Definitely!  Which comes back to the question of "not useful enough".  This
seems very useful and important to me!

> However, unless the compiler can infer the
> actual implemention type, a slower dispatch mechanism would have
> to be used.

Not necessarily.  C++ and Microsoft's COM both support quick dispatch, via
virtual function tables, of methods invoked on explicitly declared
interfaces.  The implementation type doesn't have to be known if each
interface has its own dispatch table for each implementation.  The ability
to support this performance hack is another (lesser) reason that it's useful
to explicitly declare the interfaces that a class supports.