I think most everyone is missing the new simplicity of the current
conception of "multi".  It's now completely orthogonal to scoping
issues.  It merely says, "I'm putting multiple names into a spot
that would ordinarily demand a unique name."

In other words, what a name means in a given scope is a kind of
invariant--there's no magic hocus pocus in which multimethod dispatch
suddenly "steals" calls from ordinary method dispatch.

This is actually more powerful than the usual multimethods.  To get
the usual behavior of multimethods in other languages, you have to
explicitly declare the multimethods in global space:

    multi sub *add( Foo $foo, Bar $bar );

If you write:

    multi sub add( Foo $foo, Bar $bar );

then the current package has multiple add routines, but they aren't global.

If you write:

    multi my sub add( Foo $foo, Bar $bar );

then the current *lexical* scope has multiple add routines!

If you write:

    multi method add( $self: Foo $foo, Bar $bar );

then there are multiple add methods in the current class.  Note the
invocant is not optional in this case.  Also, there's an implied
second colon after $bar, indicating the end of the arguments to be
considered for multi dispatch.  (You can put as many colons as you
want in any multi declaration--each subsequent colon indicates that
the preceding additional argument or arguments are to be used as
"tie breakers, just as Foo and Bar are being used for tie-breaking
in the method above.)  Likewise for submethods:

    multi submethod add( $self: Foo $foo, Bar $bar );

In essence, the compiler could implement "multi" by taking any such
set of identically named routines and implementing them as a single
routine with switching logic to tell the types apart.

One ramification of all this is that "true" multimethods must always
be called as subroutines, not as methods.

I hope this clarifies things a bit.  Well, more than a bit...

Larry

Reply via email to