
sub cprod2 (\@\@) {
  my ($a, $b) = @_;
  cprods($a, $b);
}

sub cprods ($$) {
  my ($a, $b) = @_;
  my $by_e = sub { my $x = shift; map { [@$x, $_]} @$b };
  map {$by_e->($_)} @$a;
}

sub cprod {
  return () if @_ == 0;
  my @r = map {[$_]} @{shift()};
  while (@_) {
    @r = cprods(\@r, shift());
  }
  @r;
}


@a = ('a' .. 'c');
@b = (1..4);
@c = qw(red yellow blue);

@d = cprod(\@a, \@b, \@c);
1;
1;
1;

for (@d) {
  local $" = ', ';
  print "(@$_)\n";
}
