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

Multidimensional argument list binding (*@;foo)

2 views
Skip to first unread message

Ingo Blechschmidt

unread,
Nov 20, 2005, 3:11:33 PM11/20/05
to perl6-l...@perl.org
Hi,

quoting r6624 of S06 [1]:
> Some functions take multiple Lists that they wish not to be flattened
> into one list. For instance, C<zip()> wants to iterate several lists
> in parallel, while array and hash subscripts want to process
> multidimensional slices. The set of underlying argument list (List)
> objects may be bound to a single array parameter declared with a C<;>
> twigil:
>
> sub foo (*@;slices) { ... }

sub foo (*@;AoA) { @;AoA }

my @array1 = <a b c>;
my @array2 = <d e f>;

my @AoA = foo @array1, @array2;
say +@AoA; # 2?
say ~@AoA[0]; # a b c?
say ~@AoA[1]; # d e f?
# Correct?


foo 1, 2;
# dies (neither 1 nor 2 are arrays)?

foo $arrayref1, $arrayref2;
# dies (neither $arrayref1 nor $arrayref2 are arrays)?

foo();
# works, +foo() is 0?


Also, is specifying other, non-slurpy arguments prior to a slurpy
@;multidim_arglist legal? E.g.:

sub bar ($normal_var, @;AoA) {...}
bar 42, @array1, @array2;
# $normal_var is 42,
# @AoA is (\@array1, \@array2)
# Correct?


The existence of a @array variable does not imply the existence of a
@;array variable, right?


--Ingo

[1] http://svn.perl.org/perl6/doc/trunk/design/syn/S06.pod

Luke Palmer

unread,
Nov 20, 2005, 9:38:31 PM11/20/05
to Ingo Blechschmidt, perl6-l...@perl.org
On 11/20/05, Ingo Blechschmidt <ibl...@web.de> wrote:
> sub foo (*@;AoA) { @;AoA }
>
> my @array1 = <a b c>;
> my @array2 = <d e f>;
>
> my @AoA = foo @array1, @array2;
> say +@AoA; # 2?

1

> say ~@AoA[0]; # a b c?

a b c d e f

However,

my @AoA = foo(@array1; @array2);
# all of Ingo's predictions are now correct

> foo 1, 2;
> # dies (neither 1 nor 2 are arrays)?

Nope. The return value would be [[1,2]].

> foo $arrayref1, $arrayref2;
> # dies (neither $arrayref1 nor $arrayref2 are arrays)?

Returns [[$arrayref1, $arrayref2]] (a three-dimensional array).

> foo();
> # works, +foo() is 0?

Hmm. Hard to say whether that would be [] or [[]].

Luke

Ingo Blechschmidt

unread,
Nov 21, 2005, 9:51:53 AM11/21/05
to perl6-l...@perl.org
Hi,

Luke Palmer wrote:
> On 11/20/05, Ingo Blechschmidt <ibl...@web.de> wrote:
>> sub foo (*@;AoA) { @;AoA }
>>
>> my @array1 = <a b c>;
>> my @array2 = <d e f>;
>>
>> my @AoA = foo @array1, @array2;
>> say +@AoA; # 2?
>
> 1
>
>> say ~@AoA[0]; # a b c?
>
> a b c d e f
>
> However,
>
> my @AoA = foo(@array1; @array2);
> # all of Ingo's predictions are now correct

Hm. How is (*@;AoA) different from (Array *@AoA) then? (Assuming that
foo(@a; @b) desugars to foo(\@a, \@b).)


--Ingo

Luke Palmer

unread,
Nov 21, 2005, 10:48:30 AM11/21/05
to Ingo Blechschmidt, perl6-l...@perl.org
On 11/21/05, Ingo Blechschmidt <ibl...@web.de> wrote:
> Hm. How is (*@;AoA) different from (Array *@AoA) then? (Assuming that
> foo(@a; @b) desugars to foo(\@a, \@b).)

Well, it's not at all, under that assumption. But that assumption is
wrong. I think foo(@a; @b) doesn't have a sugar-free form (that is to
say, it is the sugar-free form). Among things that desugar to it:

@a ==> foo() <== @b
foo(@a) <== @b
@a ==> @b ==> foo() # maybe; don't remember

To illustrate:

sub foo (*@a) {
say +@a;
}
sub bar (*@;a) {
say +@;a;
}
foo(1,2,3; 4,5,6); # 6
bar(1,2,3; 4,5,6); # 2

That is, the regular *@a has "concat" semantics. However, I'd like to
argue that it should have "die" semantics, for obvious reasons.

Luke

Ingo Blechschmidt

unread,
Nov 21, 2005, 1:49:16 PM11/21/05
to perl6-l...@perl.org
Hi,

Luke Palmer wrote:
> On 11/21/05, Ingo Blechschmidt <ibl...@web.de> wrote:
>> Hm. How is (*@;AoA) different from (Array *@AoA) then? (Assuming that
>> foo(@a; @b) desugars to foo(\@a, \@b).)
>
> Well, it's not at all, under that assumption. But that assumption is
> wrong.

Aha! FYI, I got that interpretation from r6628 of S09 [1]:
> The following two constructs are structurally indistinguishable:
>
> (0..10; 1,2,4; 3)
> ([0..10], [1,2,3,4], [3])

> I think foo(@a; @b) doesn't have a sugar-free form (that is to
> say, it is the sugar-free form). Among things that desugar to it:
>
> @a ==> foo() <== @b
> foo(@a) <== @b
> @a ==> @b ==> foo() # maybe; don't remember
>
> To illustrate:
>
> sub foo (*@a) {
> say +@a;
> }
> sub bar (*@;a) {
> say +@;a;
> }
> foo(1,2,3; 4,5,6); # 6
> bar(1,2,3; 4,5,6); # 2
>
> That is, the regular *@a has "concat" semantics. However, I'd like to
> argue that it should have "die" semantics, for obvious reasons.

Just to clarify -- only ";" with "*@;a" should have "die" semantics, ","
with "*@;a" should continue to work, right? (If so, I agree.)

Could you provide some more examples with ;, please? In particular, what
are the results of the following expressions?

(42; 23)
(@a; @b)
(@a; @b)[0]
(@a; @b)[0][0]

((42;23); (17;19))
((@a;@b); (@c;@d))

*(42; 23)
*(@a; @b)

( (42; 23), 19)
(*(42; 23), 19)

[42; 23]
[@a; @b]


Thanks very much,

--Ingo

[1] http://svn.perl.org/perl6/doc/trunk/design/syn/S09.pod
/The semicolon operator

Larry Wall

unread,
Nov 21, 2005, 2:26:23 PM11/21/05
to perl6-l...@perl.org
On Mon, Nov 21, 2005 at 03:48:30PM +0000, Luke Palmer wrote:
: To illustrate:

:
: sub foo (*@a) {
: say +@a;
: }
: sub bar (*@;a) {
: say +@;a;
: }
: foo(1,2,3; 4,5,6); # 6
: bar(1,2,3; 4,5,6); # 2
:
: That is, the regular *@a has "concat" semantics. However, I'd like to
: argue that it should have "die" semantics, for obvious reasons.

Well, that can be argued both ways. The Unix shells get along very well
with default concat semantics, thank you:

(echo foo; echo bar; echo baz) | grep a

And it's rather Perlish to give you a level of flattening for free when
it comes to lists. And I'd like to be able to distinguish:

my @foo := gather {
for @whatever {
take .generate();
}
}

from

my @;foo := gather {
for @whatever {
take .generate();
}
}

though I think maybe I'm arguing that the ; there is just documentation
if @;foo and @foo are really the same variable, and it's the differing
usage in rvalue context that desugars @;foo to [;]foo.dims.

Larry

Larry Wall

unread,
Nov 21, 2005, 2:12:18 PM11/21/05
to perl6-l...@perl.org
On Sun, Nov 20, 2005 at 09:11:33PM +0100, Ingo Blechschmidt wrote:
: Also, is specifying other, non-slurpy arguments prior to a slurpy
: @;multidim_arglist legal?

Yes, though we have to be careful about what happens when we bind the
entire first dimension and then get a <== boundary. That's probably
not intended to produce an empty first dimension. On the other hand,
maybe it just falls out of the policy that .[] is a null dimension
unless you actually put something there, and maye that extends to
.[;stuff] and even .[;;;;;;;;stuff].

: E.g.:


:
: sub bar ($normal_var, @;AoA) {...}
: bar 42, @array1, @array2;
: # $normal_var is 42,
: # @AoA is (\@array1, \@array2)
: # Correct?

No, these are specifically not AoA.

: The existence of a @array variable does not imply the existence of a
: @;array variable, right?

I think it probably does, or should. @;array is sugar for something
like [;]@array.specs, presuming that .specs clumps its slices into
single iterators (which it doesn't), and also presuming that you could
use [;] in a declarative context (which you can't). So it's more like
[;]@array.dims, which is an array of slice generators each of which
is a sublist of iterators. It's probably not an array of arrays
internally, but just a list of specs with some of them marked as starting
a new dimension.

We originally were modeling the multidimension stuff on AoA, but we
kept getting tangled up in intentional vs unintentional brackets.
We need to be able to support the userland flat view of an array and
still be able to get at its specs anyway, so this is basically trying
to handle multislices/multidims/multipipes with the same underlying
mechanism.

Larry

Larry Wall

unread,
Nov 21, 2005, 2:29:29 PM11/21/05
to perl6-l...@perl.org
On Mon, Nov 21, 2005 at 07:49:16PM +0100, Ingo Blechschmidt wrote:
: Aha! FYI, I got that interpretation from r6628 of S09 [1]:

: > The following two constructs are structurally indistinguishable:
: >
: > (0..10; 1,2,4; 3)
: > ([0..10], [1,2,3,4], [3])

Sorry, started revising that one a couple days ago and got sidetracked...

Larry

0 new messages