No. A::L::NestLoops provides an iterator; List::Comprehensions takes a callback.
By way of example, you mentioned iterating an N-dimensional 'lattice', (by which I assume you mean 'array'), that you don't know how many dimensions it will have until runtime. If you run the following code it will select a 2,3, or 4 dimension array at random and then iterate it printing out the indices and values:
#! perl -slw use strict; use List::Comprehensions; sub expandDims { return unless ref $_[ 0 ] eq 'ARRAY'; return [ 0 .. $#{ $_[ 0 ] } ], expandDims( $_[ 0 ][ 0 ] ); } my $ref2D = [ map [ 0 .. 2 ], 0..3 ]; my $ref3D = [ map [ map [ 0..1 ], 0..2, ], 0..3 ]; my $ref4D = [ map [ map [ map [ 0..1 ], 0..2, ], 0..3 ], 0..4 ]; my $ref = ( $ref2D, $ref3D, $ref4D )[ rand 3 ]; comp1 { my $val = $ref; $val = $val->[ $_ ] for @_; printf "[%s] := %s\n", join('][', @_), $val; } expandDims( $ref );
The output looks like this:
c:\test>junk4 [0][0] := 0 [0][1] := 1 [0][2] := 2 [1][0] := 0 [1][1] := 1 [1][2] := 2 [2][0] := 0 [2][1] := 1 [2][2] := 2 [3][0] := 0 [3][1] := 1 [3][2] := 2 c:\test>junk4 [0][0][0] := 0 [0][0][1] := 1 [0][1][0] := 0 [0][1][1] := 1 [0][2][0] := 0 [0][2][1] := 1 [1][0][0] := 0 ... [3][0][0] := 0 [3][0][1] := 1 [3][1][0] := 0 [3][1][1] := 1 [3][2][0] := 0 [3][2][1] := 1 c:\test>junk4 [0][0][0][0] := 0 [0][0][0][1] := 1 [0][0][1][0] := 0 [0][0][1][1] := 1 [0][0][2][0] := 0 ... [4][3][0][0] := 0 [4][3][0][1] := 1 [4][3][1][0] := 0 [4][3][1][1] := 1 [4][3][2][0] := 0 [4][3][2][1] := 1
Not very interesting, but it demonstrates both discovering the dimensions of the AoA(...) at runtime and then iterating it.
There is a flaw in L::C, relative to FP language equivalents. Namely, that although it will accept multiple 'guard' subs interspersed with the array refs as input, the guard sub are called en-masses with all the generated arguments just prior to the main callback. In (for example) Haskell, the guard subs are called in their input order with just the arguments that precede (right to left) them in the input list.
The advantage of A::Ls iterator is that you can abandon the iterator at any time, where L::Cs callback will be called for the entire set of combinations. Though you can suppress entry to the main callback by returning nothing from a guard sub. For example, if you change last line of the code above to this:
} sub{ "@_" =~ /2/ ? () : @_ }, expandDims( $ref );
Then the main callback code will not be called if any of the indices is a 2. For the 2D array, the output then becomes:
c:\test>junk4 [0][0] := 0 [0][1] := 1 [1][0] := 0 [1][1] := 1 [3][0] := 0 [3][1] := 1
The main advantage (for me) of L::C is that I find the syntax more amenable to the way I think.
In reply to Re^3: loop over n-dimensional lattice
by BrowserUk
in thread loop over n-dimensional lattice
by 0AP0
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |