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