Re: Re: Do interfaces make sense in multiple dispatch languages?

Bryn Keller <[email protected]>
Newsgroups gmane.comp.lang.nice.general
Message-ID <[email protected]>
Hi  Brian,

[email protected] wrote:

>Now, the three methods concerning the loan all define some contract between
>graduate students and undergraduates. But, they don't have anything to do with 
>tutoring. So, we have two different contracts over the same pair of types. But
>the contracts are not part of the types GraduateStudent or UndergraduateStudent.
>
>In your example, we can add another method in a different package:
>
>    package a.b.c;
>    void disposeAndNotify(Disposable);
>
>Did we change the contract of nice.lang.Disposable? I don't think we did. 
>  
>
The contract of an interface is exactly those methods which do something 
new for each type that implements the interface. These methods are 
declared, but not implemented. Methods which are defined in terms of 
already existing methods that are part of the contract do not extend the 
contract, and in Nice, this would be reflected by defining a default 
implementation for that method:

<Disposable D> void disposeAndNotify(D d) {
    synchronized(d) {
        d.dispose();
        d.notify();
    }
}

So you're exactly right, disposeAndNotify isn't part of the contract of 
Disposable, since it can be implemented purely in terms of the existing 
Disposable contract (and its supertypes, in this case).

>Anyway, according to using.nice, Disposable is an abstract interface, not an
>interface. This is something that I found very confusing when I started using
>Nice: two different things called "interface." An "abstract interface" does not
>introduce a type while "interface" does. 
>
In Daniel's papers these are called 'kinds', and I think that might 
actually be a better name.

>Yet, abstract interfaces can be used in
>the same contexts that interfaces can.
>
Not quite. They are more like Haskell type classes - you can use them 
for constraints on type parameters, but they're not really types, so you 
can't have a List<Disposable> or let Disposable foo =... Come to think 
of it, I'm not even sure you could wrap them up in an existential type 
for that purpose like you could in Haskell... at least, not without casting.

class DisposableHolder {
    private Object obj;
}

<Disposable T> new DisposableHolder(T thing) {
    this(obj: object(thing));
}

<Disposable T> T get(DisposableHolder holder) = cast(holder.obj.cast);

let List<DisposableHolder> = new ArrayList();

would be my best guess, but it doesn't compile...


> Plus, I don't believe that "abstract
>interface" relates to "interface" the same way "abstract class" relates to
>"class." I am often confused about whether to use an abstract interface or a
>regular interface. I always have to think of abstract interfaces as analogous to
>O'Caml functors in order to figure out how they can/should be used.
>  
>
I'm probably missing some of the subtleties, but I only use an abstract 
interface whenever I need to include third-party types (like 
OutputStream, in using.nice). Otherwise I find regular interfaces more 
convenient, and if regular interfaces could be applied to pre-existing 
classes, I'm not sure what use there would be for abstract interfaces. 
Daniel, have I forgotten something important?
 
Bryn


-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.