On Wed, Jul 13, 2005 at 06:11:32PM +1000, Damian Conway wrote: : TSa (Thomas Sandlaß) wrote: : : >> Unique least-inherited most-specialized match, or default : > : > : >Do I read this correctly as dispatching partly in the class hierarchy : >and partly in the type hierarchy? : : Err. The class hierarchy *is* the type hierarchy in Perl 6.
Implicit is that role distance is N + the distance to the nearest class that incorporates that role for small values of N. If class Dog does role Bark and also does role Wag, then passing a Dog to multi (Bark $x) multi (Wag $x) should result in ambiguity. The interesting question is whether N should be 0 or 1 (or possibly epsilon). If we have multi (Bark $x) multi (Dog $x) arguably Dog is more specialized than Bark, which says N maybe shouldn't be 0. Whether it should be epsilon or 1 depends on how you think of role composition, and whether you think of roles more like immediate parent classes or generic paste-ins. You can think of them as immediate parent classes, but in that case they're actually closer than a real parent class that would have distance 1, since role methods override parent class methods. That argues for N < 1. The problem with N == epsilon is in visualizing how Dog is more constrained than Bark. It is constrained, but its constraint is that a class is required to be about a real object (or a fake real object in the case of the Class object), whereas a role is not so constrained. This is inside out from the view that "a role is a class that isn't allowed to create an object", but while that's stated as a constraint, it's a constraint in the service of more generality rather than more specificity. So it's more accurate to say something like "a class is a role that is constrained to deal with concrete objects". It's sort of a "where exists" constraint. So I could be happy with either 0 or epsilon. 0 is simpler, and fits better with the role flattening world view. Epsilon has the additional problem that it's, er, additive rather than subtractive in this case. If we say Bark where Wag, it's simultaneously more specialized and less specialized. I think epsilons should be restricted to explicit "where" counting, though I'm liberal on the subject of whether those explicit "where" mentions are in the actual signature or in a subtype declaration somewhere. I suspect these should be equivalent distance in where-space: sub ( $x of Int where { $_ % 1 } ) subtype Odd of Int where { $_ % 1 } sub { Odd $x } I suppose a case could be made that a Bark could be considered more constrained than a Dog, which would solve the addition/subtraction problem, but it still violates the explicit-where dictum. So I'm still in favor of 0 distance for role composition. Note, however, that run-time mixins can increase distance by one if they have to create an anonymous class. Additional mixins may or may not increase the distance depending on whether the mixin mechanism creates additional anonymous classes or just adds more roles to the existing anonymous class. The former approach is probably cleaner, and we don't really need the latter mechanism to compose multiple mixins into an anonymous class simultaneously, assuming we can stack $mammal does Bark does Wag; and get some kind of list-associative simultaneous precedence. Or maybe that should be spelled $mammal does Bark&Wag; Larry