On Saturday, July 19, 2003, at 04:25 AM, Luke Palmer wrote:

In Objective-C:

    id untyped = somefunction();
    id<Foo> typed = otherfunction();

If you send a message to C<typed> which isn't in the C<Foo> protocol
definition, you get warnings.  Depending on the implementation, that
assignment might be dynamically interface-checked.

This is even nicer in function signatures, where accidental polymorphism is an amazingly nice thing. If saying:


        # quite possibly broken syntax
        method debug ( String $s )
        {
                print $s.to_string;
        };

really means 'String or a derived class', you're missing out on things that support &to_string.

That's really the fault of whoever wrote this method, but I'd prefer the language guide people to make better decisions.

Now on to the implementation.

Inheritance feels like the wrong way to mark interface equivalence. Take, for example, an object that combines a FloorWax and a DessertTopping. Delegation's the way to go here, but if I have to inherit from both FloorWax and DessertTopping to signify that the object (somehow) implements both protocols appropriately, there are subtler problems remaining. It might inherit behavior from a common ancestor to both classes and then there's a diamond pattern.

Inheritance answers two questions. First, how does this class relate to other things I know about? Second, where do instances of this class get behavior?

The first is a deeper question -- besides inheritance, there's delegation, aggregation, and reimplementation (think mock objects) that can make two classes have equivalent interfaces. I'd like some way to mark this equivalence *without* having to inherit from an abstract base class and I wish that interface equivalence were checked before inheritance, as per Luke's idea.

Class::ActsLike does something similar in Perl 5.

-- c



Reply via email to