Multi subs in Perl 6 support two features:
What do they mean?
my multi foo (Foo $a) {...};
for 1..4 {
my multi foo (Bar $a) {...};
# foo(Bar) is visible here
}
# but not here
class A {};
class B is A {};
multi foo (A $a) { say 1 };
multi foo (B $a) { say 2 };
foo(A.new());
foo(B.new());
Most languages that support multi dispatch doesn't support this feature, this is usually seen as a compile-time error, since the two variant are ambiguous. But this is a very important feature to Perl 6, since that's how objects can overload most operators. Which means you need a disambiguation code to sort all the matching candidates.
The dispatching would implement the following steps:
class MultiSub {
has @.variants;
}
module MultiSubDispatcher {
only sub lookup ($name, $capture, $lexpad, $package) --> Code {...}
only sub dispatch ($name, $capture, $lexpad, $package) --> Object {
lookup($name, $capture, $lexpad, $package).($capture);
}
}
role MultiVariantDisambiguator {
only sub disambiguate (*@variants) --> Code {...}
}
Each variant declaration could hold a cache of all the outer declarations already sorted, meaning that it would just consume the first element of the lazy return of grep. Of course runtime declarations would drop the cache entirely and it would need to be rebuilt.