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

[email protected]
Newsgroups gmane.comp.lang.nice.general
Message-ID <[email protected]>
Quoting Daniel Bonniot <[email protected]>:

> > 1. What to do with "interfaces" in Nice
> > 
> > I think that the term "interface" and the phrase "implements interface" are
> > both very confusing because they do not match the underlying abstract model 
> > of the language. In Java, we can say that an interface introduces a type 
> > with a set of operations defined on that type; the set of methods is the 
> > "interface". In Nice, all we can say is that an interface introduces a type;
> > it does not define a set of methods. 
> 
> But if you say (adapting from Bryn's implementation of 'using') :
> 
>    interface Disposable {}
> 
>    void dispose(Disposable);
> 
> There is a "contract" attached to Disposable, which is that you must 
> implement a dispose method. It's just that since you can define methods 
> operating on Disposable anywhere, this contract is open to extensions.

I think this is not a good way of thinking about this. Why is the contract
attached to the interface Disposable and not to the method dispose(Disposable)?
It seems the contract is really attached to the method dispose at least as much
as it is to the interface Disposable. Furthermore, your example is too
simplistic. Pick a method that takes two parameters. How do you decide what
interface this method belongs too? Is the method part of the first parameter
type's contract or the second parameter type's contract? I think actually the
method is either part of the contract of the *package* it belongs to, or we have
to generalize the concept of contract analogously to the way single dispatch was
generalized to multiple dispatch. As an analogy, when I borrow money from you,
we will have a contract specifying the terms of the loan. Who does the contract
belong to? I say it belongs to neither of us, but rather it describes some set
of interactions between us, something like:
      interface GraduateStudent { }
      interface UndergraduateStudent { }

      void enter_loan_agreement(GraduateStudent rich,
                                UndergraduateStudent poor,
                                BigDecimal begin)
           requires begin >= 0.0
           ensures equals(balance(rich, poor), begin) { ... }
      BigDecimal balance(GraduateStudent rich,
                         PoorUndergraduateStudent poor) { ... }
      void end_loan_agreement(GraduateStudent rich,
                              UndergraduateStudent poor)
           requires equals(balance(rich, poor), ZERO) { ... }

      void tutor(GraduateStudent stud, UndergraduateStudent dumb,
                 int hours) { ... }

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. 

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. Yet, abstract interfaces can be used in
the same contexts that interfaces can. 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.

> > Actually, with multiple inheritence it makes sense to have a "interface"
> > or "type" construct if you were planning to distinguish between types vs.
> > classes, and subtyping vs. subclassing. For example, if you wanted to 
> > support "class X subclasses Y { }" where X inherits everything from class Y 
> > but without meaing that X <: Y.
> 
> Is there any reason to want that? 

I think it a useful example would be:
    class X { ... }
    class Y { ... }
    class Z extends Y implements X { ... }

You want Z <: X and Z <: Y but perhaps you don't want to (or can't, in the
single inheritence case) have Z inherit fields from X.

> > The more I think about this the more it seems I am suggesting that the Nice
> team
> > re-implement Cecil. We should make a language comparison between Cecil and
> Nice
> > to see what the advantages of each are.
> 
> If I remember correctly, Cecil started as a dynamically typed language, 
> and they worked on adding a static type-checker to it, but I don't think 
> it's complete. The type system is in any case very different from 
> Nice's, which was the initial motivation to work on Nice. They have a 

Cecil had a well-specified type system but it was never proven decidable and a
typechecker was never compleletly implemented for it. Anyway, my observation is
that Cecil and other multiple dispatch languages I know of also support multiple
inheritence; maybe this is not a cooincidence? Cecil also seperates classes from
types and has the block call syntax I quoted on the Wiki. I believe that the
changes I describe are mostly syntactical and the semantic ones (e.g. multiple
inheritence) can be implemented via desurgaring be compatible with Nice's
current type system.

- Brian




-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
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.