On Tuesday, March 11, 2003, at 11:19 AM, Austin Hastings wrote:
But you can't wrap multi-ness, as far as I can tell.
[A6] And it happens that the multimethod dispatch is smart enough to find the ordinary single-invocant sysread method, even though it may not have been explicitly declared a multimethod. Multimethod dispatch happens to map directly onto ordinary method dispatch when there's only one invocant.
At least, that's how it works this week... [/A6]
To me, this suggests that multithods can be bolted on top of unithods. And presumably, likewise multisubs can be bolted atop Plain Old Subs (POSs).
I *think* that's just talking about the internal dispatch mechanism... e.g. the dispatcher treats one-invocant subs and multis the same way, and can map between them if necessary -- I don't think it's talking about the semantic/syntactic rules for declaring them, just the guts of what happens when you eventually call one.
So I still surmise it's a semantic error to override a C<sub> with a C<multi>. (It doesn't have to be, internally, but otherwise I'm not sure why you'd want a separate keyword C<multi> at all.)
sub foo($a,$b,$c) {...}
... lots of code inbetween ...
multi foo(int $a) {...} # ERROR - can't multi an existing sub multi foo(str $a) {...}
In your example, where you have two separate modules that both have a C<foo>:
module CPANthing; sub foo($x) {...}
module MyThing; sub foo($x) {...} # ERROR - redefined: multi won't, but "my" will fix sub foo(int $x) {...} # ERROR - must use multi
multi foo(int $x) {...} # OK multi foo($x: @a) {...} # OK multi foo($x: ?$y = 0) {...} # WARNING: compile-time or run-time?
I would put the errors in different places, because there's nothing wrong with having an identically named function in two different namespaces, right? So I would rewrite that:
module CPANthing; sub foo($x) {...}
module MyThing; sub foo($x) {...} # OK - we're in a different namespace now sub foo(int $x) {...} # ERROR - must use multi
multi foo(int $x) {...} # ERROR - can't multi an existing sub multi foo($x: @a) {...} multi foo($x: ?$y = 0) {...}
Or am I completely spacing on something?
MikeL