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.
Correct. > 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" } vs. 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 Larry