Michel J Lambert:
# I was curious if anyone has ever considered implementing multimethod
# dispatch (MMD) directly into parrot. In my opinion, this would provide
# several benefits over the current system. While (IMHO) MMD
# provides many
# benefits over the current system in terms of extensibility and ease of
# maintainence, it is still a superset of single-dispatch
# systems, and could
# easily be made to support non-MMD languages like Python, Perl6, etc.

Perl 6 will almost certainly be a multimethod language.  (Remember, the
insane Aussie is sharing the helm. :^) )

# Parrot has been doing some questionable things, in my mind,
# to get around
# the lack of multimethod dispatch. First, there are basic
# native types such
# as num, int, and string, which I'm perfectly fine with. But
# what bothers
# me is the fact that bigint's and bignum's are being given a
# special place
# in the vtable. If we can't get these classes working with the
# base types
# properly without putting them in the core and vtable itself,
# how can we
# expect users to make such things as complex numbers and
# matrices mesh with
# the system?

BigInts and BigNums are in the core because we want regular types to
convert to Big types whenever there's an overflow.  Other types can
easily be implemented as objects.

# In MMD, A.add(B) in OOP terms would be dispatched to an add function
# specifically registered for A and B, instead of just calling add on A.
# This difference is not apparent when dealing with the parrot
# native types,
# since they already provide different functions for add_int
# and add_num.
# But if you're a PMC, as just about every perl variable will
# be, you get
# the generic treatment and are given an add, or at best, an
# add_same. I'm
# proposing to extend that to allow there to be different add
# functions for
# specific PMC types.

Most methods in Parrot will be handled through a "call method" vtable
function.  Most multimethod dispatch will probably be handled there.
Only things that operators do (basically) will be handled by other
vtable functions.

To a degree, the existing vtable functions are already polymorphic:

        return SELF->data.integer + value->get_integer(INTERP, value);

Yeah, that's kind of a "not really", but you get the idea.

I imagine that for overloading we'll have a system similar to what we
have for Perl 5:  PerlInt::add will see if its right operand has an add
and if it's an object type, and hand off accordingly.

# Some might argue that this leads to an explosion of type
# registrations,
# since a single class must register itself with every type out
# there. This
# could be solved by allowing them to register a given function
# for PMC's in
# general (the existing way, basically), and allow a few
# specific functions
# for specific types they would like to handle directly.
#
# MMD would also allow users who had code that dealt with
# Math::BigInt and
# Math::BigInteger to write routines to coerce between the two types
# *without* requiring participation of the original module writers or
# editing of those packages. They could write something for
# add(BigInt,BigInteger), coercion functions, and suddenly their two
# incompatible pieces of code will be able to work together, hopefully
# seamlessly.

Neither will exist, since we have bigints in the core.  But I understand
your meaning.  This can be best handled at the language level, not the
Parrot level.  (At the Parrot level, you'd probably have to fiddle to
some degree with the two classes, unless Perl rewrote the code while you
weren't looking to call the custom operator:+.)

# With parrot, this could be implemented to allow Perl* types
# to interact
# with Parrot* types, providing automatic conversion and
# interaction between
# the two types of PMCs, by whoever decides to make the interface work
# between the two languages. This wouldn't require any additions to the
# perl* types or parrot* types, but could be written independantly, and
# registered with the parrot system at loadtime.

There will be very few Parrot* types.  Notice that the only one we
currently have is ParrotPointer.

# Others might say that multimethod dispatch is too slow. There
# are numerous
# papers out there on implementing multimethod dispatch
# efficiently, such
# as:
# http://citeseer.nj.nec.com/amiel96fast.html
# http://citeseer.nj.nec.com/495443.html
# http://citeseer.nj.nec.com/ferragina99multimethod.html
# http://citeseer.nj.nec.com/330853.html
# http://citeseer.nj.nec.com/pang99multimethod.html
# and so on and so on... I haven't read them myself, but a quick search
# proved to find many available papers out there.

I don't have time to read those, but if they require heavy compile-time
analysis they won't work well for Parrot.  Most of it's languages are
compile-and-go.  (Yes, I'm sure there are quick ways to do multimethods.

# Regardless, MMD will still be slower than the current parrot vtable
# dispatch system, and that point is unavoidable. One could argue that
# vtable dispatch is slower than a generic 'add' function, too. But the
# benefits provided by vtables to avoid spaghetti if/else code more than
# outweigh the disadvantages. I'd argue that the same logic
# would apply to
# MMD as well.

But at some point you need to draw the line.  The decision to use
vtables was as much because we would be loading new PMC classes at
runtime (which would require somehow magically rewriting the if-else
series) as it was to avoid an if-else series or a switch.  (Besides,
when the if-else series or switch gets very large, vtables are probably
faster.)

# Finally, here's a real-world example of code that could be
# improved. :)
# perlint needs to handle addition to strings, nums, ints, perlstrings,
# perlnums, perlints, and other pmc's. The first three are
# covered by their
# individual functions, the next two are implemented by if/else's in the
# generic add function, and perlints get called via add_same.
# This variety
# of function names and approachs just seems wasteful, and MMD could
# potentially simplify a lot of this into one function per type, with a
# consistent scheme.
#
# Any thoughts or comments on this? Is this a case of 'patches
# welcome' for
# the current system, but no one's seen a need for it? Or is there an
# argument against implementing MMD in the core parrot?

It's something that needs a lot of deep, serious design thought by the
designers.  It's not something that can just be patched and you skip
merrily along your way.

To sum up:  I think MMD is a good idea, but I don't think it belongs in
the vtables.  Perhaps in the subroutine call sequences, but not in the
vtables themselves.  It might even be within the arena of the languages
themselves, if different languages have different rules for deciding
which multimethod to use.

--Brent Dax <[EMAIL PROTECTED]>
@roles=map {"Parrot $_"} qw(embedding regexen Configure)

#define private public
    --Spotted in a C++ program just before a #include

Reply via email to