#### Approaches:

##### 1.Metaprogramming

Generate dynamically a string of the above code with all nesting and eval it. (fast and intuitive!)

##### 2. Recursion

Write a function X2() which gets two arrayrefs and returns an arr_ref of the cross product. Call it recursively until @array exceeded.

##### 3. Reduce

is a variation of the above, with List::Util::reduce

```use Data::Dumper;

#- crossproduct of two array refs
sub X2 {
my (\$a,\$b)=@_;
my @result;
for my \$x (@\$a) {
for my \$y (@\$b) {
unless (ref(\$x) eq "ARRAY"){
push @result, [\$x,\$y];
}else{
push @result, [(@\$x,\$y)];
}
}
}
return \@result;
}

use List::Util qw/reduce/;

#- crossproduct of list of array refs
sub X { reduce { X2(\$a,\$b) } @_ }

my @array = (
[ "a", "b", "c", ],
[ "1", "2", "3", "4", ],
[ "x", "y", ],
);

print Dumper X(@array);

The function X() now works somehow like the X operator in perl6, but of course you could also use reduce { X2(\$a,\$b) } @array directly.

The function X2() could be rewritten with two nested maps, but thats a little two cryptic for my taste.