On Thu, Mar 27, 2008 at 09:02:37AM -0600, Thom Boyer wrote:
> Larry Wall wrote:
>> The .++ form is still not a method (single) dispatch, just an alternate
>> form of the postfix, which is a multi dispatch.  
> But the postfix is a unary operator, right? So that'd be multi dispatch on 
> one argument.


> How does single dispatch differ from multi dispatch on a single argument?

The question is, who's to be master, that's all.  :)

Single dispatch asks the object's MOP (meta-object protocol) to
dispatch through its .HOW interface, so it depends on which metaobject
system the object was born under.

Multiple dispatch, in contrast, pays attention only to the type
information that comes from the .WHAT interface, and doesn't ask
the MOP to do the dispatch.  It is external to any MOP, except
insofar as the MOP gets involved to help define how .WHAT returns
type information.  But types are considered largely declarative,
not procedural.

(This view of single dispatch is slightly oversimplified, insofar
as the MOP typically sets up an efficient responder interface that
handles the actual dispatch without having to redecide every time.)

Practically speaking, the main difference is "foo $x" looks for
a function with one argument, while $x.foo looks for a method
with no arguments.

    multi sub foo ($x) { say "I am a function" }
    method foo () { say "I am a method" }

The candidate list for multis is constructed from all longnames visible
in the current lexical scope, and there is no inheritance involved,
only importation of function names (which, for so-called built-in
functions, is done by the Prelude from the various modules those
functions are defined in).

The candidate list for methods is determined by the MOP, but generally
follows class hierarchy for class-based OO.

A routine can be visible via both routes, but only by some form of
aliasing.  The "close" method/function is defined something like:

    class IO;
    method close () is export {...}

and when the Prelude does "use IO" it imports the close method not
as method, but as a function, as if you'd said:

    multi close (IO $self) {...}

or some such.

And since mutlis are lexically scoped, and operators are just macros
that translate to function calls, and longnames from different scopes
are interleaved, it means we have lexically-scoped overloading if
you want it.

The other ramification is that we get to define our operators
independently of what the object might think the operator means,
even if it comes from another language.  These may mean two entirely
different things if $a comes from, say, Python or Java or Perl 5:

    $a + $b             # always addition in Perl 6
    $a.'+'($b)          # depends on language of $a

More subtly, the same distinction happens with unaries:

    +$a                 # always numification in Perl 6
    $a.prefix<+>        # depends on language of $a


Reply via email to