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;


Reply via email to