I have been reading up on method resolution orders and class precedence lists and all sort of meta-model esoteria. Which brings me to ask myself, "How should all this be done in Perl 6?".

The current state of the prototype meta-model is that it only supports pre-order class traversal (like Perl 5). However we are not limited to this, the framework needed to support other traversal methods is now in place.

Basically in order to implement submethods as described by Larry (having an implicit "next METHOD if $?SELF != $?CLASS" in front of it), I needed to implement a stateful dispatcher. This made it very easy to then implement WALKMETH and WALKCLASS, which the metamodel now uses for dispatching, and then to also make 'next METHOD' (implemented as next_METHOD() in the prototype).

So this brings me to some questions regarding various traversal methods listed in A12, they are:

    :canonical      # canonical dispatch order
    :ascendant      # most-derived first, like destruction order
    :descendant     # least-derived first, like construction order
    :preorder       # like Perl 5 dispatch
    :breadth        # like multimethod dispatch

My first question is, how is the dispatch order changed? I assume it is through the %opt argument in WALKMETH and WALKCLASS.

My second question is, who would really be changing this? Is this something Perl 6 will utilize internally? Will other things be implemented which require these different traversal orders? Basically, what good is having all these different traversal orders?

And lastly I have questions on each particular ordering.

- canonical

What would be considered the "canonical" method dispatch? I would assume it would mean the traditional Perl 5 style (pre-order).

- preorder

Is this not the canonical way in Perl?

- breadth

I can see the usefulness of this if you are going to handle your own WALKMETH, but wouldn't CALLONE, CALLALL handle this same behavior? Or maybe I am not understanding its usefulness.

- ascendant/descendant

These two are the tricky ones, especially with multiple inheritance. But thankfully there is much work already done on this subject, and all we need to do is pick the one we like and copy... uh *ahem* borrow ... it :)

So my question is this, given the following class layout:

    A      Least derived
   / \
  B   C
  |   |
  D   E
   \ /
    F      Most Derived

What is the method resolution order (for ascendant order)?

  F, D, E, B, C, A


  F, D, B, E, C, A

The first one would follow a "strict" most-derived order, but will probably not be what the user will expect. It also looks a lot like breadth first traversal.

The second one is what all the other "cool kids" seem to be doing. It is called "Monotonic Superclass Linearization" or "C3" and it is what Guido and the boys are doing for Python 2.3. The original paper is on the language Dylan (http://www.webcom.com/haahr/dylan/linearization-oopsla96.html) and gives a pretty good explaination. And it is detailed again in this paper on python (http://www.python.org/2.3/mro.html). If you read both of these papers (even just skimming them) you will see that this approach makes a lot of sense. However it does impose some restrictions on funky MI class composition which we would need to deal with. Basically it should blow up in certain cases where the method cannot properly be resolved no matter what (the papers give several examples of this).

Personally I would go with the second one. It seems to "feel right" to me, and I like anything which blows up in the face of overwhelming ambiguity :)

I wonder too if we choose to use C3, then if that should not become the canonical way?



Reply via email to