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

Re: Multimethods 101 (was Re: Multiple dispatch (Re: Q: Python 2.0 preliminary features?))



Bruce Hoult wrote:
> 
> In article <381A421D.D8C8E22F@bigfoot.com>, Louis Madon
> <madonl@bigfoot.com> wrote:
> 
> > [I'm cross-posting this to comp.lang.dylan as I think the Dylaners' may
> > be able to cast more light on this and/or correct any short-comings in
> > my thinking]
> >
> >
> > In the beginning Greg Ewing wrote:
> >
> > > Suppose AA is a subclass of A, and BB is a subclass of B,
> > > and there are methods defined for the combinations
> > > foo(A, B), foo(AA, B) and foo(A, BB).
> > >
> > > Now, if you make a call with the combination foo(AA, BB),
> > > which method should get called?
> >
> >
> > Several people said its "ambiguous".
> 
> Interesting case.
> 
> Certainly it's ambiguous.
> 
> I note that the ambiguity can arise *only* if some module that (directly
> or indirectly) calls foo() also (directly or indirectly) depends on both
> AA and BB.
> 
> For example, you suggested that maybe something in module X calls
> something in module Y, passing it a BB.  Module Y creates an AA (which X
> doesn't know about) and calls foo(AA, BB).  oops.  The only place that
> this problem can be detected at compile-time is in module X, and then only
> if the compiler knows that module Y imports both AA and foo EVEN IF IT
> DOESN'T RE-EXPORT THEM.  This seems like a big ask.

I agree, but isn't that what runtime exceptions are for?

> 
> I'm wondering what the semantics of the exact situation are.  Will the
> right result occur if foo(A, BB) or foo(AA, B) is called for arguments of
> type (AA, BB)?

I think the semantics need to be really simple: if there's any doubt
throw an exception.  If the system starts making guesses about whether
this method or that method could handle it, it might get it wrong, and I
think it also makes reasoning about the program more difficult.

>  If not then perhaps foo() is trying to do too much and
> should be split up?  In particular, perhaps there should instead be a
> bar(A) and baz(B) and just a single, generic, version of foo(A, B) that
> calls bar(A) and baz(B) as part of its operation.  In which case the
> implementator of AA should make a bar(AA) and the implementatior of BB
> should make a baz(BB). And then all is sweetness and light :-)

You're not suggesting explicit type tests inside foo(A, B) are you? 
Thats precisely the kind of thing we need to get away from.  I could
come along and define a new class AB that inherits from both A and B and
all of a sudden your typecase is broken.

Louis.



Follow-Ups: References: