Larry Wall wrote:
On Tue, Aug 05, 2008 at 06:17:30PM +0200, Jonathan Worthington wrote:
Hi,
I am currently reviewing bits of the spec surrounding multiple dispatch
and, of course, have a question or two (I'll probably have some more
later, as the dust settles in my head).
1) The spec says:
--
A proto also adds an implicit multi to all routines of
the same short name within its scope, unless they have an explicit modifier.
--
If you write:
proto sub foo(:$thing) { ... }
sub foo(Int $x) { ... }
only sub foo() { ... }
Does this give some kind of error, because you've declared something
with 'only', but it clearly can't be the only one because we also have a
proto in there?
I'd consider it an error.
OK, sounds sane.
2) If I write:
multi sub foo(Int $blah) { ... } # 1
proto sub foo(:$blah) is thingy { ... } # 2
multi sub foo() { ... } # 3
Does #1 get the thingy trait, or not because it was declared before the
proto was? I'm clear that #3 gets it...
I think a proto cannot be expected to work retroactively. In fact, I
think it's probably an error to declare a proto after a non-proto in the same
scope.
OK, error for this also seems sane.
3) The spec says:
--
A parameter list may have at most one double semicolon; parameters after
it are
never considered for multiple dispatch (except of course that they can
still
"veto" if their number or types mismatch).
--
Does the "veto" take place once the multiple dispatch has given us a
candidate and we try to bind the parameters to the signature, or as part
of the multiple dispatch? For example, supposing I declare:
multi foo(Int $a;; Num $b) { ... } # 1
multi foo(Int $a;; Str $b) { ... } # 2
multi foo(Int $a;; Num $b, Num $c) { ... } # 3
What happens with these?
foo(2, RandomThing.new); # Ambiguous dispatch error
foo(2, 2.5); # Ambiguous dispatch error, or 1 because 2 vetos?
foo(1, 2.5, 3.4); # Ambiguous dispatch error, or 3 because only one with
arity match?
Basically, what I'm getting at is, are all of these multi-methods
ambiguous because they all have the same long name, and just because
binding fails doesn't make us return into the multiple dispatch
algorithm? (This is what I'm kinda expecting and would mean every one of
these fails. But I just want to check that is what was meant by the
wording.)
I believe "veto" is giving the wrong idea here as something that
happens after the fact. What's the term for only allowing "acceptable"
candidates to put their names on the ballot?
I'm not sure, but since we're carving up the set of possible candidates
so the dispatcher only sees those that could bind, maybe we should go
for "gerrymandering". ;-)
Anyway, as TSa surmises, the ballot is vetted or stacked in advance--only those
candidates that *could* bind are considered to be part of the candidate set.
OK, so that would seem to mean that if we're looking at what could bind
then we also check the arity and the type constraints of the non-MMD
parameters (after the C<;;>) during the dispatch. So for my examples
we'd get:
foo(2, RandomThing.new); # No matching candidates error
foo(2, 2.5); # Only 1 is a candidate, so we get that
foo(1, 2.5, 3.4); # Only 3 is a candidate, so we get that
In the abstract, candidates that cannot match never get their names
on the ballot, though of course an implementation might choose to
determine this lazily as long as it preserves the same semantics.
I'm thinking mine will do this bit lazily, at least in the first cut.
Alternately, even if the list of valid candidates is determined
eagerly, if the candidate list construction is memoized based on the
typeshape of the Capture, it will generally not have to be redone
until you see a different typeshape (where the meaning of "different"
may depend on how specific the signatures are, and in particular on
whether any of the signatures rely on subset constraints (including
individual values, which are just degenerate subsets)).
*nod* That sounds like we're starting to wonder down the road of
optimizations though, and I'd rather do something simple and correct
first, at least until there's a large enough body of tests to be sure
that optimizations aren't making us just get the wrong answers really
quickly.
Thanks,
Jonathan