multi sub and invocants (related to colon question from earlier)

2005-05-17 Thread Aaron Sherman
There's some ambiguity in A/S 6 that I wanted to ask about.

A6 says:

Ordinary subs never have an invocant. If you want to declare a
non-method subroutine that behaves as a method, you should
declare a submethod instead.

But S6 changes that without fully explaining itself:

Multimethod and multisub invocants are specified at the start of
the parameter list, with a colon terminating the list of
invocants

S12 sayeth:

Ordinarily all the arguments of a multi sub are considered
invocants
[...]
The caller indicates whether to use single dispatch or multiple
dispatch by the call syntax. The dot form and the indirect
object form default to single dispatch. Subroutine calls with
multiple arguments and operators with multiple operands default
to multiple dispatch.

Ok, so here we are. I'm told on #perl6 that you can't have something
like:

class Num {
method abs() returns Num { ... }
}
multi sub abs(Num $i:) returns Num { ... }

because you're not allowed to define both multi and single-dispatch
methods on a class.

Let's say that that's true. You can certainly still end up in conflict:

class A {...}
my A $a = A.new() but role { method x() {...} }
eval 'multi sub x(A $i:) {...}';

Now, the eval should work because A has no x method, but you do now have
a $a which will conflict on $a.x

According to the above bit from S12, $a.x calls single dispatch first,
so it should call the anonymous role's method x, right?

If I wanted to call the multi, I could aways say: x($a), couldn't I?

-- 
Aaron Sherman [EMAIL PROTECTED]
Senior Systems Engineer and Toolsmith
It's the sound of a satellite saying, 'get me down!' -Shriekback




Re: multi sub and invocants (related to colon question from earlier)

2005-05-17 Thread Luke Palmer
On 5/17/05, Aaron Sherman [EMAIL PROTECTED] wrote:
 Let's say that that's true. You can certainly still end up in conflict:
 
 class A {...}
 my A $a = A.new() but role { method x() {...} }
 eval 'multi sub x(A $i:) {...}';
 
 Now, the eval should work because A has no x method, but you do now have
 a $a which will conflict on $a.x

Well, the way I see it is like so:

class A {...}
class A_anonymous_role is A { method x() {...} }
my A $a = A_anonymous_role.new;
eval 'multi sub x(A $i:)';

And that the method gets called because it's more specific than the
multi.  But that's assuming the transformation:

class A { method x() {...} }

To:

multi sub x(A $self:) {...}

Which could be wrong.  I think I have pretty good cause to infer that, though.

Luke