それ内部イテレータ

うはは、無理矢理。コードを生成して、eval するなら、そりゃそっちのが速いよなぁ。
つうか、逆転の発想というより、そりゃ外部イテレータが内部イテレータに変わっているって話だ。いやまぁ、別にいいっちゃいいんだけど、内部イテレータ有りならもっと素直に書いてたな。こんなの。

use strict;
use warnings;

sub mesh_iterate {
    my ( $sub, @points ) = @_;

    my $base = pop @points;

    unless (@points) {
        for my $i (@$base) {
            $sub->($i);
        }
    }
    else {
        mesh_iterate(
            sub {
                for my $i (@$base) {
                    $sub->( @_, $i );
                }
            },
            @points
        );
    }
}

mesh_iterate(
    sub {
        printf "[%s]\n", join(', ', @_);
    },
    map { [ 0 .. 3 ] } 0 .. 2
);

ついでに、H.I. さんに提示してもらったコードはこんな感じ。(細部のスタイルは勝手に変更)

use strict;
use warnings;

sub mesh_iterator {
    return sub { } unless @_;

    my $lasts = pop;
    my $itsub = mesh_iterator(@_);
    my ($idx, @butlast) = (-1, $itsub->());

    return sub {
        ($idx, @butlast) = (0, $itsub->()) and @butlast || return()
            if ++$idx >= @$lasts;
        return @butlast, $lasts->[$idx];
    };
}

my $iter = mesh_iterator( ([0..9]) x 3 );
while (my @p = $iter->()) {
    printf "[%s]\n", join(', ', @p);
}

おお、うまい。というか、素直に考えればこうか。でも、何やっているんだか瞬時にはわかんないすね。世の Perl 使いはこういうのも瞬時に理解できるんだろうか。
もうちょっと読みやすくするとすればこうかな。

use strict;
use warnings;

sub mesh_iterator {
    return sub { }
      unless @_;

    my $lasts = pop;
    my $itsub = mesh_iterator(@_);
    my ( $idx, @butlast ) = ( 0, $itsub->() );

    return sub {
        if ( $idx < @$lasts ) {
            return @butlast, $lasts->[ $idx++ ];
        }
        else {
            ( $idx, @butlast ) = ( 0, $itsub->() );
            return @butlast, $lasts->[ $idx++ ] if @butlast;
            return;
        }
    };
}

my $iter = mesh_iterator( ( [ 0 .. 9 ] ) x 3 );
while ( my @p = $iter->() ) {
    printf "[%s]\n", join( ', ', @p );
}

で、何気に

なお、Perl6 ではyieldもサポートされる予定です。

む、そうなのか。期待。