Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

multi method dispatching of optional arguments

4 views
Skip to first unread message

Mark Stosberg

unread,
Sep 2, 2006, 8:52:57 PM9/2/06
to perl6-l...@perl.org
Hello,

I think it would helpful if the spec addressed "who wins" in MMD when
optional arguments are present.

I just submitted these failing tests for pugs which illustrate the
issue.

not ok 11 - Arguments (a => 'b') to signatures 1. () and 2. (*%h) calls 2
not ok 14 - Arguments () to signatures 1. (@a?) and 2. () calls 2
not ok 15 - Arguments (<1 2 3>) to signatures 1. () and 2. (@a?) calls 2

In summary, matches that should otherwise happen are failing because
the "optionalness".

Mark

Reference:
http://feather.perl6.nl/syn/S12.html#Multisubs_and_Multimethods

Mark Stosberg

unread,
Sep 2, 2006, 9:48:18 PM9/2/06
to perl6-l...@perl.org
Mark Stosberg wrote:
> Hello,
>
> I think it would helpful if the spec addressed "who wins" in MMD when
> optional arguments are present.
>
> I just submitted these failing tests for pugs which illustrate the
> issue.
>
> not ok 11 - Arguments (a => 'b') to signatures 1. () and 2. (*%h) calls 2
> not ok 14 - Arguments () to signatures 1. (@a?) and 2. () calls 2
> not ok 15 - Arguments (<1 2 3>) to signatures 1. () and 2. (@a?) calls 2
>
> In summary, matches that should otherwise happen are failing because
> the "optionalness".
>
> Reference:
> http://feather.perl6.nl/syn/S12.html#Multisubs_and_Multimethods

I just patched mmd-draft.txt in the pugs tree to try address optionals.
Here's what I came up with:

== Handling Optional and Slurpy Parameters

Optional parameters need special consideration, because they represent
two options themselves: one with with the argument and one without.
Slurpy parameters have the same concern, as they can take zero or more
arguments themselves. For each optional parameter, a case with and
without the optional parameter is considered.

Examples:

Arguments (a => 'b') to signatures 1. () and 2. (*%h) calls 2

Arguments () to signatures 1. (@a?) and 2. () calls 2

Arguments (<1 2 3>) to signatures 1. () and 2. (@a?) calls 2

Mark

Mark Stosberg

unread,
Sep 2, 2006, 10:47:31 PM9/2/06
to perl6-l...@perl.org
Mark Stosberg wrote:
> Hello,
>
> I think it would helpful if the spec addressed "who wins" in MMD when
> optional arguments are present.
>
> I just submitted these failing tests for pugs which illustrate the
> issue.
>
> not ok 11 - Arguments (a => 'b') to signatures 1. () and 2. (*%h) calls 2
> not ok 14 - Arguments () to signatures 1. (@a?) and 2. () calls 2
> not ok 15 - Arguments (<1 2 3>) to signatures 1. () and 2. (@a?) calls 2
>
> In summary, matches that should otherwise happen are failing because
> the "optionalness".
>
> Reference:
> http://feather.perl6.nl/syn/S12.html#Multisubs_and_Multimethods

I took a break and thought of an important further clarification for
this. The updated text is below:

== Handling Optional and Slurpy Parameters

Optional parameters need special consideration, because they represent
two options themselves: one with with the argument and one without.
Slurpy parameters have the same concern, as they can take zero or more
arguments themselves. For each optional parameter, a case with and
without the optional parameter is considered.

Examples:

Arguments (a => 'b') to signatures 1. () and 2. (*%h) calls 2
Arguments (<1 2>) to signatures 1. (@a?) and 2. (@a) calls 2


Arguments (<1 2 3>) to signatures 1. () and 2. (@a?) calls 2

Arguments (@a) to signatures 1. (@a?) and 2. (@a) IS TIE

Note that the variant /with/ the parameter can be considered an exact
match, but but the variant /without/ it cannot be considered an exact
match. That rule makes the following example work:

Luke Palmer

unread,
Sep 2, 2006, 10:00:57 PM9/2/06
to Mark Stosberg, perl6-l...@perl.org
I don't follow your examples. What is the logic behind them?

On 9/3/06, Mark Stosberg <ma...@summersault.com> wrote:
> Examples:


> Arguments (<1 2>) to signatures 1. (@a?) and 2. (@a) calls 2

For example, I would expect this one to be ambiguous, because the 1.
(@a?) sub introduces two different signatures, 1. () and 1. (@a).
When given <1 2>, 1. (@a) matches as well as 2. (@a), so it is
ambiguous.

> Arguments (@a) to signatures 1. (@a?) and 2. (@a) IS TIE

The only difference I can see between this and the one above is @a vs.
<1 2>, which ought to behave the same way, right?

> Note that the variant /with/ the parameter can be considered an exact
> match, but but the variant /without/ it cannot be considered an exact
> match.

And I expect that if either or both matches the method is considered
to be a match. Right?

Luke

Mark Stosberg

unread,
Sep 3, 2006, 8:25:58 AM9/3/06
to perl6-l...@perl.org
Luke Palmer wrote:
> I don't follow your examples. What is the logic behind them?
>
> On 9/3/06, Mark Stosberg <ma...@summersault.com> wrote:
>> Examples:
>> Arguments (<1 2>) to signatures 1. (@a?) and 2. (@a) calls 2
>
> For example, I would expect this one to be ambiguous, because the 1.
> (@a?) sub introduces two different signatures, 1. () and 1. (@a).
> When given <1 2>, 1. (@a) matches as well as 2. (@a), so it is
> ambiguous.

Oops. Yes, I would call that a tie, too.

>> Arguments (@a) to signatures 1. (@a?) and 2. (@a) IS TIE
>
> The only difference I can see between this and the one above is @a vs.
> <1 2>, which ought to behave the same way, right?

Yes.

>> Note that the variant /with/ the parameter can be considered an exact
>> match, but but the variant /without/ it cannot be considered an exact
>> match.
>
> And I expect that if either or both matches the method is considered
> to be a match. Right?

Let's look again at the last example:

Arguments () to signatures 1. (@a?) and 2. () calls 2

(@a?) really means () OR (@a). The "()" implicit in (@a?) is a match,
but not an exact match, so the "()" declared by itself wins, because it
/is/ an exact match.

Mark

Ph. Marek

unread,
Sep 4, 2006, 12:24:11 AM9/4/06
to perl6-l...@perl.org, Mark Stosberg
On Sunday 03 September 2006 14:25, Mark Stosberg wrote:

> Luke Palmer wrote:
> > On 9/3/06, Mark Stosberg <ma...@summersault.com> wrote:
> >> Note that the variant /with/ the parameter can be considered an exact
> >> match, but but the variant /without/ it cannot be considered an exact
> >> match.
Excuse me for getting into this thread with only minor knowledge about perl6,
but will there be MMD based on the *value* of parameters? Like Haskell has.

I don't know about a possible syntax, but sometimes it's a very nice way to
dispatch to different parts.

(I know that that's possible with if statements, but they have a disadvantage:
they're not so visually "dispatching", if you know what I mean).


Regards,

Phil

Audrey Tang

unread,
Sep 4, 2006, 10:21:32 AM9/4/06
to Ph. Marek, perl6-l...@perl.org, Mark Stosberg
2006/9/4, Ph. Marek <philip...@bmlv.gv.at>:

> On Sunday 03 September 2006 14:25, Mark Stosberg wrote:
> > Luke Palmer wrote:
> > > On 9/3/06, Mark Stosberg <ma...@summersault.com> wrote:
> > >> Note that the variant /with/ the parameter can be considered an exact
> > >> match, but but the variant /without/ it cannot be considered an exact
> > >> match.
> Excuse me for getting into this thread with only minor knowledge about perl6,
> but will there be MMD based on the *value* of parameters? Like Haskell has.

Why, yes, see the various Unpacking sections in S06, as well as "where"
type constraints. We're st^H^Hadapting as much as we can. :-)

Audrey

Ph. Marek

unread,
Sep 5, 2006, 1:29:35 AM9/5/06
to aud...@audreyt.org, perl6-l...@perl.org, Mark Stosberg
On Monday 04 September 2006 16:21, Audrey Tang wrote:
> 2006/9/4, Ph. Marek <philip...@bmlv.gv.at>:

> > Excuse me for getting into this thread with only minor knowledge about
> > perl6, but will there be MMD based on the *value* of parameters? Like
> > Haskell has.
>
> Why, yes, see the various Unpacking sections in S06, as well as "where"
> type constraints. We're st^H^Hadapting as much as we can. :-)
Hello Audrey!


I now had a look at http://dev.perl.org/perl6/doc/design/syn/S06.html but
didn't find what I meant.
Sorry if I'm just dumb and don't understand you (or S06); I'll try to explain
what I mean.


In Haskell you can eg. write:

SomeThing :: Int -> Int -> Int
SomeThing a b
| a = 4 : b+2
| b = 3 : a+1
| otherwise : a*b
or
AnotherThing :: Int -> Int -> Int
AnotherThing 4 b = b+2
AnotherThing b 3 = a+1
AnotherThing a b = a*b


In Perl5 this looks like

sub SomeThing
{
my($a, $b)=@_;

return b+2 if ($a == 4);
return a+1 if ($b == 3);
return a*b;
}

Which is a bit wrong IMO, because the condition should be first.
But
sub SomeThing
{
my($a, $b)=@_;

if ($a == 4) { return b+2 }
if ($b == 3) { return a+1 }
return a*b;
}
is a bit of a hazzle with the {} and repeated if()s.


What I am asking is whether there will be some multimethod dispatch depending
on the *value*, not the *type*, of parameters.
Perl6 could possibly do something with "given"; but matching on multiple
variables seems to be verbose, too.
I'm looking for something in the way of

sub SomeThing(Num $a, Num $b) where $a==4 is $b+2;
sub SomeThing(Num $a, Num $b) where $b==3 is $a+1;
sub SomeThing(Num $a, Num $b) { return $a * $b }

but without specifying the signature multiple times (or maybe we should, since
it's MMD). Now

sub SomeThing(Num $a, Num $b)
{
if $a==4 { return $b+2; }
if $b==3 { return $a+1; }
return $a * $b;
}

would almost do what I want, but I don't know if the compiler would optimize
that in the way it could for direct MMD depending on types.


Regards,

Phil

Trey Harris

unread,
Sep 5, 2006, 1:52:35 AM9/5/06
to Ph. Marek, aud...@audreyt.org, perl6-l...@perl.org, Mark Stosberg
In a message dated Tue, 5 Sep 2006, Ph. Marek writes:
> I now had a look at http://dev.perl.org/perl6/doc/design/syn/S06.html
> but didn't find what I meant. Sorry if I'm just dumb and don't
> understand you (or S06); I'll try to explain what I mean.

I don't think you're dumb; the Synopses just require that you intuit
certain things from each other, from examples in other Synopses, and so on
in a Perlish sort of way; what you're looking for is not spelled out
explicitly. It can be found by noticing how you specify subtypes, along
with noticing that subtypes can be specified as parameter types. There's
also an example showing explicitly what you want in S12.

> In Perl5 this looks like
>
> sub SomeThing
> {
> my($a, $b)=@_;
>
> return b+2 if ($a == 4);
> return a+1 if ($b == 3);
> return a*b;
> }

> [...]


> What I am asking is whether there will be some multimethod dispatch depending
> on the *value*, not the *type*, of parameters.
> Perl6 could possibly do something with "given"; but matching on multiple
> variables seems to be verbose, too.
> I'm looking for something in the way of
>
> sub SomeThing(Num $a, Num $b) where $a==4 is $b+2;
> sub SomeThing(Num $a, Num $b) where $b==3 is $a+1;
> sub SomeThing(Num $a, Num $b) { return $a * $b }

It's just

multi sub SomeThing(Num $a where {$^a == 4}, Num $b) { $b + 2 }
multi sub SomeThing(Num $a, Num $b where {$^b == 3}) { $a + 1 }
multi sub SomeThing(Num $a, Num $b) { $a * $b }

> but without specifying the signature multiple times (or maybe we should, since
> it's MMD). Now

Yes, the signatures are different--the first two multis specify subtypes
as their signatures, the last specifies a canonical type.

Trey

Ph. Marek

unread,
Sep 5, 2006, 2:01:31 AM9/5/06
to Trey Harris, aud...@audreyt.org, perl6-l...@perl.org, Mark Stosberg
On Tuesday 05 September 2006 07:52, Trey Harris wrote:
> I don't think you're dumb; the Synopses just require that you intuit
> certain things from each other, from examples in other Synopses, and so on
> in a Perlish sort of way; what you're looking for is not spelled out
> explicitly. It can be found by noticing how you specify subtypes, along
> with noticing that subtypes can be specified as parameter types. There's
> also an example showing explicitly what you want in S12.
Ok, I'll try to dive through the documentation before asking questions.

> It's just
>
> multi sub SomeThing(Num $a where {$^a == 4}, Num $b) { $b + 2 }
> multi sub SomeThing(Num $a, Num $b where {$^b == 3}) { $a + 1 }
> multi sub SomeThing(Num $a, Num $b) { $a * $b }
>

> Yes, the signatures are different--the first two multis specify subtypes
> as their signatures, the last specifies a canonical type.

Thank you *very* much! That clears it up.


Regards,

Phil

Ruud H.G. van Tol

unread,
Sep 5, 2006, 6:44:38 AM9/5/06
to perl6-l...@perl.org
Ph. Marek schreef:


> [Haskell]


> SomeThing a b
> | a = 4 : b+2
> | b = 3 : a+1
> | otherwise : a*b
>

> In Perl5 this looks like
>
> sub SomeThing
> {
> my($a, $b)=@_;
>
> return b+2 if ($a == 4);
> return a+1 if ($b == 3);
> return a*b;
> }


Or like:

sub SomeThing
{
alias my ($p, $q) = @_ ;

$p == 4 ? $q + 2 :
$q == 3 ? $p + 1 :
$p * $q ;
}

--
Groet, Ruud

Larry Wall

unread,
Sep 11, 2006, 10:30:09 AM9/11/06
to perl6-l...@perl.org

Every scalar value is a one-element subset of its type, so you can just write:

multi sub SomeThing(Num 4, Num $b) { $b + 2 }
multi sub SomeThing(Num $a, Num 3) { $a + 1 }


multi sub SomeThing(Num $a, Num $b) { $a * $b }

or even just

multi sub SomeThing(4, Num $b) { $b + 2 }
multi sub SomeThing(Num $a, 3) { $a + 1 }


multi sub SomeThing(Num $a, Num $b) { $a * $b }

Though 3 and 4 are arguably going to match against Int rather than Num...

Larry

0 new messages