Leopold Toetsch wrote:

2) n-dimensional MMD

Perl6 supports a more general form of MMD:

multi sub foo(ClassA $a, ClassB $b, ClassC $c : ...) { ... }

[snip]

4) Proposed changes:

a) All method lookup goes through VTABLE_find_method. To achieve MMD functionality, two arguments are added to the find_method signature:

   PMC* find_method(STRING* meth_name, INTVAL mmd_nr, INTVAL* mmd_flag)

mmd_nr is the MMD invocant number:

  0 := first (or only invocant)
  1 := second invocant (e.g. right argument of 2-dim MMD)
  ...

mmd_flag is a pointer to an integer, indicating the desired behavior:

The caller sets:

  mmd_flag := NULL     ... no MMD, plain method lookup
  mmd_flag := &depth   ... return the next matching method starting
                           at the given parent search depth

In the general case, how does the caller know that MMD is invoked?

A PIC scheme outperforms the current static MMD table lookup by 30% up to 70% for overloaded operations.

A cache invalidation function is called from add_method (and remove_method) which resets entries for the passed class.

And, in some languages, all calls to set_attr or setprop type methods, where the value invoked may be invokable, or might obscure visibility to one that is. As calls to setting attributes/properties are frequent, my concern is that this may more than wipe out any potential benefit that such a cache may provide.


Also, note that the Perl sub defined above is not a method.

Comments welcome,

Counter-proposal.

With Parrot today, compiler writers need not know the difference between a closure, a continuation, a coroutine, an nci, or a sub. Or, for that matter, a PyFunc, a PyGen, or a PyType.

The general case is that the caller has a PMC which "does sub". This may not be a method (the Perl syntax above suggests a simple sub). It may have been found via find_lex or find_global, been returned by a previous subroutine call, or have been newly created. Whatever.

At this point, the caller's responsibilities are merely to set up the registers according to the Parrot Calling Conventions and then execute the invoke opcode, or equivalent (invokecc, tailcall, ...).

At this point, there are two paths that are possible. Either the compiler takes full responsibility for emitting code that does the appropriate second level dispatch. Or there can be code in the Parrot repository in the form of a new subclass of the existing Sub class which locates and appropriate destination. (Note: these choices are not mutually exclusive).

I see no reason why a full multi-dimensional multi-method dispatch PMC could not commence immediately, complete with a fully-functional polymorphic inline cache. Once it is ready and tested, we can explore setting things up so that the various mmd_dispatch_* functions to exploit this functionality for the existing predefined binary operations.

- Sam Ruby

Reply via email to