Thanks for your very detailed explanation of your views on the Pure
MMD scheme, Damian.  I finally understand why you're opposed to it.  I
could never really buy your previous argument: "Manhattan distance is
better".

Damian writes:
> Similarly, since the number of potential variants is the Cartesian product of
> the total sizes of the class hierarch(y|ies) for each parameter position,
> getting adequate coverage of the MMD search space quickly becomes tedious if
> most of the search space is (by default) ambiguous, as in "pure ordering"
> dispatch schemes.

Indeed, pure MMD will be ambiguous in more cases.  If you think
narrowly, then it causes you to write many disambiguating cases which
*usually* end up being what a manhattan metric would give you anyway. 
But you can get away from that terrible duplication by being more
precise about your types.  You can define type classes using empty
roles[1], where you simply organize your type dag into abstractions
that make sense to your dispatcher.  The upshot of all this is that it
forces you to think in a way so that the "*usually*" above becomes an
"always".  And it involves defining more (very small) types that make
sense to humans, not gratuitously many MMD variants which are pretty
hard to think about.

> One very common problem with pure ordering schemes is that subsequent changes
> in one or more class hierarchies can cause previously unambiguous cases to
> become ambiguous, by extending a zone of ambiguity in the search space. 
> In
> contrast, because a metric approach always fully partitions the entire search
> space, hierarchy changes may alter where a particular call dispatches to, but
> only ever to a "closer", more appropriate variant.

You just made my primary argument against manhattan distance for me. 
If you change something in the middle of the class hierarchy,
manhattan distance causes multimethods on the leaves to change
semantics.  You say that pure MMD causes them to break when a change
occurs.  Isn't that better than changing?  Presumably you ran it
through the ambiguity checker and a test suite and got it right once,
and then you have to do it again when you refactor.  This comes with
the meaningless "unit derivation" that a metric scheme defines.

Perhaps I've made this argument before, but let me just ask a
question:  if B derives from A, C derives from A, and D derives from
C, is it sensible to say that D is "more derived" from A than B is? 
Now consider the following definitions:

    class A { }
    class B is A {
        method foo () { 1 }
        method bar () { 2 }
        method baz () { 3 }
    }
    class C is A {
        method foo () { 1 }
    }
    class D is C {
        method bar () { 2 }
    }

Now it looks like B is more derived than D is.  But that is, of
course, impossible to tell.  Basically I'm saying that you can't tell
the relative relationship of D and B when talking about A.  They're
both derived by some "amount" that is impossible for a compiler to
detect.  What you *can* say is that D is more derived than C.

In conclusion, the reason that manhattan distance scares me so, and
the reason that I'm not satisfied with "use mmd 'pure'" is that for
the builtins that heavily use MMD, we require *precision rather than
dwimmyness*.  A module author who /inserts/ a type in the standard
hierarchy can change the semantics of things that aren't aware that
that type even exists.  If you're going to go messing with the
standard types, you'd better be clear about your abstractions, and if
you're not, the program deserves to die, not "dwim" around it.

Oh, and the mmd style should probably look like:

    multi foo (...) is mmd<pure> {...}
    multi bar (...) is mmd<manhattan> {...}

Rather than a pragma.

> Note too that Perl 6 *will* still support a form of "pure ordered" dispatch--a
> left-most-closest-match scheme like that used by CLOS--via "invocant groups":
> 
>         multi sub Foo(A: B: C:) {...}
>         multi sub Foo(A: D: C:) {...}
>         multi sub Foo(F: B: G:) {...}
> 
> This, of course, is not "global pure ordering", but rather "left-biased pure
> ordering".
> 
> To summarize: pure ordering renders more of the MMD search space "ambiguous",
> which is potentially safer but much less DWIMish. Metric schemes have far
> fewer ambiguities and usually dispatch in an predictable way. Metric schemes
> can still provide pure-ordering analyses via static analysis tools or special
> warning modes, but pure ordering schemes can't avoid ambiguities or DWIM.
> 
> Of course, none of this prevents:
> 
>         use MMD <pure>;
> 
> 
> Damian

Luke

[1] And I find this to be useful even when using manhattan distance. 
I'd like to be able to define such type classes out-of-band, like:

    role Foo
        defines Bar  # Bar does Foo now
        defines Baz  # Baz does Foo now
    { }

Reply via email to