Leopold Toetsch wrote:
Sam Ruby wrote:

Leopold Toetsch wrote:

However, from <http://www.perl.com/pub/a/2004/04/16/a12.html?page=10>:

    Whenever you make a call using subroutine call syntax, it's a
    candidate for multiple dispatch.

I read this to mean that the *caller* does nothing to distinguish
between calls to single dispatch subroutines from multiple dispatch
subroutines.

So... how does one determine at compile time which opcode to use?

This probably needs some clarification from Perl6 people. Anyway, if Parrot just gets:


  foo(Px, Py, Pz)

there is no information, how many invocants are participating in MMD. So candidates for multiple dispatch must be declared somewhere.

A few things to note: "foo" is a PMC. It therefore is an object. It can have state (properties, attributes, etc). It can "know" how many arguments are involved in multiple dispatch.


All calls to "foo" are likely to have the same number of arguments participating in MMD. This number is known when foo is defined. If that information is captured in the PMC itself, it can be exploited at runtime.

$a.foo($b, $c) := foo($a, $b, $c)

Given the latter syntax, how does the compiler know when to emit a <callmethodcc "foo"> and when to emit a <call_MMD "foo">?

The compiler has to know it. E.g.

  foo($a: $b, $c);      # 1 invocant
  foo($a, $b: $c);      # 2 MMD invocants

and as Parrot has to find a method depending on n MMD invocants, this information must be present at runtime. This leads to the assumption that we'll need an opcode

call_MMD "meth", n_invocants

Changing the external syntax for subroutine calls in P6 may be an option. Changing the syntax for function calls in Python is not an option. Therefore, if changing the syntax is required, it is likely that Python will not be able to call arbitrary subroutines involving MMD.


It would be ideal if callers did not have to know how such subroutines were defined, and could continue to emit "invokecc" sequences on Sub PMCs, and for this to be handled at runtime.

and some changes in pdd03 as the current calling scheme doesn't have anything about argument order. I have described that in subject:

  "MMD: more implications"

The only thing I am attempting to solve is the presumption that MMD
calls can be detected at "compile time".

It's quite clear for infix operations like "add". For arbitrary subroutines the compiler has to know it, as outlined above.

When expressed via an infix notation, I agree that it is not a problem. When expressed via the equivalent method call notation, (as Python allows), it becomes one.


And despite that it's looking like a "fat" method call, Parrot executes this sequence, if the "__add" isn't overloaded:

  if (cache->type == (Py->vtable->base_type << 16|Pz->vtable->base_type)
     Px = (cache->function)(Py, Pz);

which is 30% faster then the current mmd_dispatch based opcode.

That code will execute just as fast if placed inside the "invoke" logic of a "MMD PMC".


- Sam Ruby

Reply via email to