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 { }