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