Perl6: Pushing an array to an array of arrays with one element seems not to work as expected Perl6: Pushing an array to an array of arrays with one element seems not to work as expected arrays arrays

Perl6: Pushing an array to an array of arrays with one element seems not to work as expected


This is the expected behavior described in the The single argument rule.

Perl 6 has been through a number of models relating to flattening during its evolution, before settling on a straightforward one known as the "single argument rule".

The single argument rule is best understood by considering the number of iterations that a for loop will do. The thing to iterate over is always treated as a single argument to the for loop, thus the name of the rule.

for 1, 2, 3 { }         # List of 3 things; 3 iterationsfor (1, 2, 3) { }       # List of 3 things; 3 iterationsfor [1, 2, 3] { }       # Array of 3 things (put in Scalars); 3 iterationsfor @a, @b { }          # List of 2 things; 2 iterationsfor (@a,) { }           # List of 1 thing; 1 iterationfor (@a) { }            # List of @a.elems things; @a.elems iterationsfor @a { }              # List of @a.elems things; @a.elems iterations

... the list constructor (the infix:<,> operator) and the array composer (the [...] circumfix) follow the rule:

[1, 2, 3]               # Array of 3 elements[@a, @b]                # Array of 2 elements[@a, 1..10]             # Array of 2 elements[@a]                    # Array with the elements of @a copied into it[1..10]                 # Array with 10 elements[$@a]                   # Array with 1 element (@a)[@a,]                   # Array with 1 element (@a)[[1]]                   # Same as [1][[1],]                  # Array with a single element that is [1][$[1]]                  # Array with a single element that is [1]

The only one of these that is likely to provide a surprise is [[1]], but it is deemed sufficiently rare that it does not warrant an exception to the very general single argument rule.

So to make this work I can write:

my @d = ( [ 1 .. 3 ], );@d.push( [ 4 .. 6 ] );@d.push( [ 7 .. 9 ] );

or also

my @d = ( $[ 1 .. 3 ] );@d.push( [ 4 .. 6 ] );@d.push( [ 7 .. 9 ] );