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

[perl #39173] Multi-Dispatch Incompatible with :flat Params

5 views
Skip to first unread message

Chromatic

unread,
May 20, 2006, 9:46:22 PM5/20/06
to bugs-bi...@rt.perl.org
# New Ticket Created by chromatic
# Please include the string: [perl #39173]
# in the subject line of all future correspondence about this issue.
# <URL: https://rt.perl.org/rt3/Ticket/Display.html?id=39173 >


The multi-dispatch signature checking code in src/mmd.c does not know anything
about :flat calls when it constructs the signature tuple for dispatching.
Here is code to demonstrate this:

.sub main :main
.local pmc int_pmc
int_pmc = new .Integer
int_pmc = 3

.local pmc args
args = new .ResizablePMCArray
push args, int_pmc
'foo'( args :flat )

.local pmc string_pmc
string_pmc = new .String
string_pmc = 'hello'

args = new .ResizablePMCArray
push args, string_pmc
'foo'( args :flat )
end
.end

.sub 'foo' :multi(Integer)
print "foo(Integer)\n"
.end

.sub 'foo' :multi(String)
print "foo(String)\n"
.end

I'll add this as a TODO test to t/pmc/mmd.t as soon as I get an RT number.

-- c

Leopold Toetsch

unread,
May 21, 2006, 6:02:13 AM5/21/06
to perl6-i...@perl.org, bugs-bi...@netlabs.develooper.com

On May 21, 2006, at 3:46, chromatic (via RT) wrote:

> The multi-dispatch signature checking code in src/mmd.c does not know
> anything
> about :flat calls when it constructs the signature tuple for
> dispatching.

Exactly. Snippets from S06:

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

If the parameter list for a "multi" contains no colon to delimit
the
list of invocant parameters, then all positional parameters are
consid-
ered invocants.
...

Invocants are the first few *positional* arguments used for a function
call, but certainly not arguments inside some kind of flattening
container.

Imagine you have instead of ...

> 'foo'( args :flat )
> end
> .end
>
> .sub 'foo' :multi(Integer)

... a :multi(int) / :multi(string). Due to autoboxing the native type
needed for dispatch would be lost.

Or - you have args with MAYBE_FLAT bit set and some slurpy and
non-slurpy sub variants. Would it first dispatch based on the
flattening aggregate, then again on the contents of it?

leo

Chromatic

unread,
May 21, 2006, 1:13:39 PM5/21/06
to parrotbug...@parrotcode.org
On Sunday 21 May 2006 03:03, Leopold Toetsch via RT wrote:

> Invocants are the first few *positional* arguments used for a function
> call, but certainly not arguments inside some kind of flattening
> container.
>
> Imagine you have instead of ...
>
> > 'foo'( args :flat )
> > end
> > .end
> >
> > .sub 'foo' :multi(Integer)
>
> ... a :multi(int) / :multi(string). Due to autoboxing the native type
> needed for dispatch would be lost.
>
> Or - you have args with MAYBE_FLAT bit set and some slurpy and
> non-slurpy sub variants. Would it first dispatch based on the
> flattening aggregate, then again on the contents of it?

That's unfortunate. I thought :flat was like the splatty behavior in Perl 6.

I can work around this for now with the C-like call_func1, call_func2, ...
call_funcN, but Parrot ought to be more dynamic than C in just about all
cases.

There ought to be a way to write the Perl 5-ish:

sub just_pass_through
{
my @args = @_;
some_other_func( @args );
}

Perhaps another attribute on invocation, perhaps :splat or :splatty?

-- c

Leopold Toetsch

unread,
May 21, 2006, 4:19:10 PM5/21/06
to chromatic, Nicholas Clark via RT

On May 21, 2006, at 19:13, chromatic wrote:

> That's unfortunate. I thought :flat was like the splatty behavior in
> Perl 6.

Reading up and down the S and As, I don't see any indication that Perl6
is using anything other then positional arguments for multi dispatch.

leo

Matt Diephouse

unread,
May 21, 2006, 4:29:34 PM5/21/06
to Leopold Toetsch, chromatic, Nicholas Clark via RT

I think chromatic means that he thought :flat _was_ positional. That's
certainly what I thought. Look at the "Flattening argument lists"
section of S06:

sub foo($x, $y, $z) {...} # expects three scalars
@onetothree = 1..3; # array stores three scalars

foo(1,2,3); # okay: three args found
foo(@onetothree); # error: only one arg
foo([,]@onetothree); # okay: @onetothree flattened to three args

In this example, $x, $y, and $z are positional args. I would expect C<
foo(1,2,3) > and C< foo([,]@onetothree) > to be identical calls --
even wrt multi dispatch. $x, $y, and $z are still positional even if
foo is called with a flattened array, right?

Autoboxing would make this a bit tougher in Parrot, but if ints box to
Integer and strings to String, then you can write your multis for
Integer and String (as chromatic did) and be done with it.

--
matt diephouse
http://matt.diephouse.com

Chromatic

unread,
May 21, 2006, 4:37:24 PM5/21/06
to ma...@diephouse.com, Leopold Toetsch, Nicholas Clark via RT
On Sunday 21 May 2006 13:29, Matt Diephouse wrote:

> I think chromatic means that he thought :flat _was_ positional. That's
> certainly what I thought.

Yes, exactly. I thought :flat and :slurpy were symmetric.

> Look at the "Flattening argument lists"
> section of S06:
>
> sub foo($x, $y, $z) {...} # expects three scalars
> @onetothree = 1..3; # array stores three scalars
>
> foo(1,2,3); # okay: three args found
> foo(@onetothree); # error: only one arg
> foo([,]@onetothree); # okay: @onetothree flattened to three
> args
>
> In this example, $x, $y, and $z are positional args. I would expect C<
> foo(1,2,3) > and C< foo([,]@onetothree) > to be identical calls --
> even wrt multi dispatch. $x, $y, and $z are still positional even if
> foo is called with a flattened array, right?

Yes. The flattening should happen at the point of the call, not at the point
of argument assignment within the call.

> Autoboxing would make this a bit tougher in Parrot, but if ints box to
> Integer and strings to String, then you can write your multis for
> Integer and String (as chromatic did) and be done with it.

I'm not sure why this matters for anything other than :slurpy; use a
primitive-holding PMC array and mark it with :flat.

(For Pheme it doesn't matter at all, as it doesn't use primitive types yet, if
ever.)

-- c

Leopold Toetsch

unread,
May 21, 2006, 4:54:28 PM5/21/06
to ma...@diephouse.com, chromatic, Nicholas Clark via RT

On May 21, 2006, at 22:29, Matt Diephouse wrote:

> foo([,]@onetothree); # okay: @onetothree flattened to
> three args
>
> In this example, $x, $y, and $z are positional args. I would expect C<
> foo(1,2,3) > and C< foo([,]@onetothree) > to be identical calls --
> even wrt multi dispatch. $x, $y, and $z are still positional even if
> foo is called with a flattened array, right?

[,] (reduce operator) is a function call, which is creating a lazy list
of 'Captures'

From S02:
o List context in Perl 6 is by default lazy. This means a
list can
contain infinite generators without blowing up. No
flattening hap-
pens to a lazy list until it is bound to the signature of a
func-
tion or method at call time (and maybe not even then). We
say that
such an argument list is "lazily flattened", meaning that we
promise to flatten the list on demand, but not before.

That's still no sign of providing multi invocants, the more that could
easily cause double dispatch - first find a multi that might or might
not slurp then possibly redispatch according to some flattened
positionals.

leo

Chromatic

unread,
May 21, 2006, 5:10:46 PM5/21/06
to Leopold Toetsch, ma...@diephouse.com, Nicholas Clark via RT
On Sunday 21 May 2006 13:54, Leopold Toetsch wrote:

> That's still no sign of providing multi invocants

From S06:

sub foo($x, $y, $z) {...} # expects three scalars

...

To flatten before the list is even passed into the subroutine, use the eager
list operator:

foo([,] eager @onetothree); # array flattened before &foo called

-- c

Leopold Toetsch

unread,
May 21, 2006, 6:22:26 PM5/21/06
to chromatic, ma...@diephouse.com, Nicholas Clark via RT

On May 21, 2006, at 23:10, chromatic wrote:

> foo([,] eager @onetothree); # array flattened before &foo
> called

Hmm, seems that another call signature bit is in order then, which
"looks" into flattening arrays for multi dispatch purposes.

leo

Chromatic

unread,
May 21, 2006, 8:26:44 PM5/21/06
to parrotbug...@parrotcode.org
On Sunday 21 May 2006 15:23, Leopold Toetsch via RT wrote:

> Hmm, seems that another call signature bit is in order then, which
> "looks" into flattening arrays for multi dispatch purposes.

I'm not sure it's just multi-dispatch; it looks like all signature checking.
The foo() in the example I quoted from S06 isn't a multi sub.

-- c

Chip Salzenberg

unread,
May 22, 2006, 2:28:05 PM5/22/06
to Leopold Toetsch, chromatic, ma...@diephouse.com, Nicholas Clark via RT

Why not just specify that :flat always expands before MMD dispatch?
I don't see much of a use case for the current behavior.
--
Chip Salzenberg <ch...@pobox.com>

Leopold Toetsch

unread,
May 22, 2006, 6:16:36 PM5/22/06
to Chip Salzenberg, ma...@diephouse.com, chromatic, Nicholas Clark via RT

On May 22, 2006, at 20:28, Chip Salzenberg wrote:

>> Hmm, seems that another call signature bit is in order then, which
>> "looks" into flattening arrays for multi dispatch purposes.
>
> Why not just specify that :flat always expands before MMD dispatch?
> I don't see much of a use case for the current behavior.

Good idea. Done that - r12753.

Thanks all for the input,
leo

0 new messages