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:

Reply via email to