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

Re: feature incompatibilities

On Mon, 2003-04-21 at 08:57, Daniel Yokomiso wrote:
>     I believe that is possible to have multimethods and modules, but the
> type system must be strong enough to solve these mismatches.

I don't really think there are any significant difficulties with modules
and multimethods.  Dylan supports both, and I've written large amounts
of Dylan code without any significant problems.  (There are several
kinds of multimethod ambiguity which have nothing to with modules; these
are discussed further down.)

Some handy rules of thumb for multimethods and modules:

  // Rule 1: Generics defined in different modules are
  // different functions.  If you import M1 and M2 into the same
  // module, you need to rename one of the f's.
  module M1
    generic f(x: Number)

  module M2
    generic f(x: String) // No relation to M1::f

  module M3
    use M1
    use M2, rename: f => other_f

  // Rule 2: Under normal circumstances, you should only add methods
  // to a generic if (a) you defined the generic in this module or (b)
  // you defined one of the method's specializer classes in this module.
  module M1
    class A ()
    generic g(x: A, y: A)
  module M2
    use M1
    class B (A)
    method  g(x: A, y: B)  // Perfectly OK--B is local.
    generic h(x: A, y: A)
    method  h(x: A, y: A)  // Perfectly OK--h is local.
    method  g(x: A, y: A)  // Not a good idea--g and A are imported.

Only methods which violate Rule 2 are in danger of doing something
unpleasant.  Dylan allows such methods, and most implementations will
report an error at link time.

The remaining sorts of ambiguities involve the CPL and method sorting

  // Possible ambiguities caused by class precedence list (CPL).
  // If you want to resolve these cleanly, use the C^3 CPL algorithm--
  // it's slightly better than Dylan's CPL rule, and *much* better than
  // Common LISP's.  You could also issue an error, if you prefer.
  class A ()
  class B (A)
  class C (A)
  class D (B,C)
  generic f(x: A)
  method  f(x: B) // Method 1
  method  f(x: C) // Method 2
  f(new D())      // Should we call method 1 or method 2?

  // Possible ambiguities caused by method sorting.  Again, you can
  // either consider this an error, or resolve it with a left-to-right
  // rule.
  class A ()
  class B (A)
  generic f(x: A, y: A)
  method  f(x: A, y: B)
  method  f(x: B, y: A)
  f(new B(), new B())   // Which method?

These two ambiguities have nothing to do with modules.

All in all, I don't see any major problems here.