Reading through the Generators page on the Python wiki inspired me to knock up something almost completely unlike generators using closures ( something Perl has that Python hasn’t… ) just for fun.

Edit: correction, thanks Bernhard.

Standard preamble…

use strict ; use warnings ;

The count() not-generator

sub count { my $cnt = -1; return sub { return ++$cnt; }; }

Helper function to make it easier to make not-generators

sub make_generator (&) { my $sub = $_ [0]; my $finished = 0; return sub { return undef if $finished; local $_ = $sub->(); $finished = 1 unless defined $_; return $_; }; }

Composing not-generators

sub compose (&$) { my ( $op , $generator ) = @_ ; return sub { local $_ = $generator->(); return undef unless defined $_; return $op->($_); }; }

Takewhile …

sub takewhile (&$) { my ( $match , $generator ) = @_ ; return make_generator { local $_ = $generator->(); return $match->($_) ? $_ : undef ; }; }

Foreach not-generator

I have to implement my own looping of course.

sub generator_for (&$) { my ( $fn , $generator ) = @_ ; while ( defined ( my $ret = $generator->())) { $fn->($ret); } }

Whew. And finally, after all that I can do the squares thing.

my $squares = compose { $_ * $_ } count(); my $bounded_squares = takewhile { $_ < 100 } $squares; generator_for { print @_ , "

" } $bounded_squares;