Author: allison Date: Thu Dec 20 00:53:11 2007 New Revision: 24108 Added: trunk/docs/pdds/pdd27_multiple_dispatch.pod
Changes in other areas also in this revision: Modified: trunk/MANIFEST Log: [pdd] Launch the Multiple Dispatch PDD. Added: trunk/docs/pdds/pdd27_multiple_dispatch.pod ============================================================================== --- (empty file) +++ trunk/docs/pdds/pdd27_multiple_dispatch.pod Thu Dec 20 00:53:11 2007 @@ -0,0 +1,215 @@ +# Copyright (C) 2007, The Perl Foundation. +# $Id: pdd00_pdd.pod 18781 2007-06-03 14:38:04Z paultcochrane $ + +=head1 NAME + +docs/pdds/pdd27_multiple_dispatch.pod - Multiple Dispatch + +=head1 ABSTRACT + +This PDD defines Parrot's multiple dispatch system. + +=head1 VERSION + +$Revision: 18781 $ + +=head1 DEFINITIONS + +Multiple dispatch allows a single function name to be associated with several +alternate implementations. It selects the alternate to execute for a +particular call at runtime, based on the types of the arguments passed into +the call. The selection process compares the arguments of the call and the +types declared in the signatures of the alternates, as well as their inherited +or composed parents, to find the best match. + +A similar selection of alternates based on types at compile time is generally +called overloading. + +=head1 DESCRIPTION + +=over 4 + +=item - Parrot supports multiple dispatch in opcodes and user-defined routines + +=item - A single dispatch system supports MMD in both contexts + +=item - For user-defined subroutines and methods, the dispatch system is +pluggable, allowing users to swap in their own type-matching algorithms + +=item - For opcodes, the dispatch system is merely extensible, allowing users +to define alternates with their own types + +=item Dispatch considers both low-level (register) types and high-level (PMC) +types, as well as inherited and composed types + +=back + +=head1 IMPLEMENTATION + +The aim of Parrot's multiple dispatch system is not to be an exact match to +any one HLL, but to provide the features and tools needed to support multiple +dispatch in a number of different HLLs. + +Parrot has a single multiple dispatch system, used at the HLL level and +internally. {{NOTE: I appreciate the history that led us to have two largely +independent MMD systems, but it will cause problems down the road, if we don't +fix it now.}} + +The heart of the system is the MultiSub PMC. All multiple dispatch routines +are MultiSub PMCs, subclasses of MultiSub, or polymorphic equivalents of +MultiSub. Calls to multiple dispatch routines use the Parrot calling +conventions. + +=head2 MultiSub PMC API + +A MultiSub stores a list of subroutines. When a MultiSub is invoked, it calls +an MMD sorting routine to select the best candidate for the current arguments, +and invokes that candidate. + +A MultiSub can be used anywhere a Sub can be used. It can be stored in a +namespace or as a method or vtable override in a class. + +An alternate multiple dispatch matching algorithm may be plugged in by +subclassing MultiSub and overriding C<invoke>. + +=head3 Vtable Functions + +MultiSub defines the following vtable functions in addition to the ones +inherited from ResizablePMCArray. + +=over 4 + +=item push_pmc + +Add a Sub or NCI sub to the list of candidates. Throw an exception if the +value passed in is anything other than a Sub or NCI sub. + +=item set_pmc_keyed_int + +Add a Sub or NCI sub to the list of candidates at a particular position in the +list. Throw an exception if the value passed in is anything other than a Sub +or NCI sub. + +=item invoke + +Invoke the best matching candidate for the current call arguments. This vtable +function calls C<Parrot_mmd_sort_candidate_list> from the public MMD API, but +may be changed to call C<Parrot_mmd_invoke>. + +=item set_integer_keyed_int, set_number_keyed_int, set_string_keyed_int + +Throw an exception, as an integer, float, or string value is not a Sub or NCI +sub. (Masks the vtable functions inherited from ResizablePMCArray.) + +=back + +=head3 PIR subroutine attributes + +The following attributes are used when declaring a MultiSub in PIR. + +=over 4 + +=item :multi + + .sub mymultisub :multi(Integer, Integer) + +The C<:multi> attribute marks a subroutine or method as participating in +multiple dispatch. + +=item :invocant + + .param pmc first :invocant + +Not all elements of a multi-sub's signature are relevant for the purposes of +multiple dispatch. The subroutine parameters that participate in dispatch are +marked with the attribute C<:invocant>. Subs that are not marked with +C<:multi> may not mark parameters with C<:invocant>. + +{{NOTE: I'm open to other names for the attribute. An English form of the +Latin I<invocare>, "to call upon", is pretty appropriate to the act of using +an argument as a selector for multiple dispatch.}} + +=back + +=head2 C Multiple Dispatch API + +These functions are the public interface to common multiple dispatch +operations, and may be called from opcodes, vtable functions, or other C +functions. + +=over 4 + +=item Parrot_mmd_sort_candidate_list + +Performs a multiple dispatch lookup on an array of subroutines. The call +signature to match is pulled from the current interpreter, following the +Parrot calling conventions. Returns a sorted array of candidates that match +the call signature, with the best matching candidate as the 0th element. + +=item Parrot_mmd_invoke + +Make a multiple dispatch call. Similar in syntax to C<Parrot_PCCINVOKE>, but +doesn't separate out the invocant before the signature since the call can have +multiple invocants. A significant part of the code from C<Parrot_PCCINVOKE> +can be factored out to helper routines used by both C<Parrot_PCCINVOKE> and +C<Parrot_mmd_invoke>. + + void + Parrot_mmd_invoke(PARROT_INTERP, NOTNULL(STRING *sub_name), + ARGIN(const char *signature), ...)> + +=item mmd_dispatch* [deprecated] + +Dispatch a routine with a fixed low-level (register) type signature, with +multiple dispatch on the high-level (PMC) types. The low-level call and return +types are specified in the name of the function: 'i' for integer, 'n' for +float, 's' for string, 'p' for PMC, and 'v' for void. So, a dispatch of one +PMC and one integer argument that returns void is a call to +C<mmd_dispatch_v_pi()>. + +=back + +=head2 Opcode Multiple Dispatch + +Parrot's basic opcodes are not multiple dispatch. They appear to be so, since +a single opcode name may have multiple signatures. But, behind the scenes, +this is essentially compile-time overloading. (Each different signature is +actually a different opcode number, hidden behind the abstraction of a single +name.) + +Multiple dispatch is only used by a limited set of opcodes. These opcodes +directly correspond to standard vtable functions. Multiple dispatch opcodes +may take PMC, integer, float, or string arguments and return a PMC, integer, +float, or string result. + +Multiple dispatch opcodes are standard opcodes that internally call the +C<Parrot_mmd_invoke> routine from the public MMD API. + +{{NOTE: It is no longer necessary to name multisubs used for opcode dispatch +using the "__" names.}} + +=head2 Vtable Multiple Dispatch + +Some PMCs call multiple dispatch routines from their vtable functions. +ResizablePMCArray, for example, calls the multiple dispatch equality operation +on each element of two arrays from the 'is_equal' vtable function. + +Multiple dispatch calls from within vtable functions call the +C<Parrot_mmd_invoke> routine from the public MMD API. + +=head1 ATTACHMENTS + +None. + +=head1 REFERENCES + +docs/mmd.pod +src/mmd.c +src/pmc/multisub.pmc + +=cut + +__END__ +Local Variables: + fill-column:78 +End: