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

Reply via email to