http://qs321.pair.com?node_id=276103
Category: Fun Stuff
Author/Contact Info thinker
Description: A Sieve of Eratosthenes implemented with closures.
I was looking over an old Java project for Uni where I had implemented a Sieve as Objects connected by pipelines.
It occurred to me closures could do a similar job far more concisely. Here was my effort. I hope this is the correct section to post in. I found it fun, anyway. :-)
#!/usr/bin/perl

# prints all prime numbers up to the value of the command line argumen
+t, or 500 if no args;

use strict;
use warnings;

use POSIX; # for ceil()

my @primes = ( 1, 2 ); #  prime the list of primes :-)    

my $max = shift || 500; 
# initialise $max if no command line argument 

my $enough = ceil ( $max ** 0.5 );
# we only need to filter until we have >= the sqrt

sub sieve {

# create a new closure to act as a part of the sieve
# the number that this closure will filter out multiples of

    my $divisor = shift;
    my $sieve_ref;

    return sub {

        my $number = shift;

# Does $number divide by divisor? 
# If so, it's not prime, so bail out;
        return unless $number % $divisor;

# if we have already created a next sieve, 
# then let it deal with the number
# pass $number to it, and return;

         if ( $sieve_ref ){
             &$sieve_ref( $number );
             return
         }; 

#if we get this far, we have a new prime

# if we need to make a new sieve to filter,do so
        $sieve_ref = sieve( $number ) if $number < $enough;

# push the prime onto the array
        push @primes, $number;
    };
};

# the main program

my $sieve = sieve( 2 ); # initialise 
&$sieve( $_ ) for 3 .. $max; 

print "The primes less than or equal to $max are @primes\n";