in reply to Re: An iterator for (not "iterating") a recursive data structure.
in thread An iterator for (not "iterating") a recursive data structure.
Should be noted that the initial problem of the OP (short-circuiting a call-back) is easily solved with goto
cbIterator { goto STOP if $_ >700; print; } \@nested; STOP:
#! perl -slw use strict; use Data::Dump qw[ pp ]; sub genNested { my $n = shift; map{ rand() < 0.5 ? [ rand(1000), genNested( $n-1 ) ] : rand( 1000 + ) } 1 .. $n; } sub cbIterator (&$) { my( $code, $tree ) = @_; for my $i ( 0 .. $#$tree ) { if( ref( $tree->[ $i ] ) eq 'ARRAY' ) { &cbIterator( $code, $tree->[ $i ] ); } else { local $_ = $tree->[ $i ]; $code->(); } } } my @nested = genNested( 3 ); pp \@nested; my $count=0; cbIterator { goto STOP if $_ >700; $count++; print; } \@nested; STOP: print "stopped after $count iterations"; __END__ [ 477.675948149653, [ 127.346865922796, [497.437228434123, 201.338051626486], 374.088657613129, ], [ 767.071185158308, [597.589516628219, 84.8516920524318], [541.772816445729, 983.763599841957], ], ] 477.675948149653 127.346865922796 497.437228434123 201.338051626486 374.088657613129 stopped after 5 iterations
Than there is some terminology confusion, in my books ( IIRC including Higher Order Perl ) this "pass a call-back" approach isn't an iterator but something I'd maybe call a diver or walker ¹, which does the iteration inside out by processing a call-back.
I.o.W for me in Perl speak:
iterator := iterator function
I checked Iterator on WP and of course there is still confusion, but at least someone proposed Iteratee
Iteratee, in which, instead of the developer calling the iterator repeatedly to get new values, the iteratee is called repeatedly to process new chunks of data - an example of inversion of control
The real problem with iterators in Perl is how to continue them after the first stop. (The OP didn't ask this)
Thats why Perl6 introduces gather/take and Python has "generators" with yield constructs.
Since you're flattening the recursion into a loop with its own call @stack , this can easily be used for such a "coroutine".
The trick is to store persisting data like @stack in the surrounding closure of the generator!
Hope this was of interest. :)
¹) I'd love to be pointed to some sources clarifying the terminology.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^3: An iterator for (not "iterating") a recursive data structure.
by BrowserUk (Patriarch) on Feb 13, 2015 at 15:29 UTC | |
by tye (Sage) on Feb 13, 2015 at 19:50 UTC | |
by LanX (Saint) on Jul 08, 2019 at 18:17 UTC | |
|
Re^3: An iterator for (not "iterating") a recursive data structure.
by MidLifeXis (Monsignor) on Feb 13, 2015 at 14:38 UTC | |
by LanX (Saint) on Feb 13, 2015 at 14:43 UTC | |
by MidLifeXis (Monsignor) on Feb 13, 2015 at 14:49 UTC |