Stories
Slash Boxes
Comments

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Journal of markjugg (792)

Thursday September 14, 2006
10:59 PM

Reduction operators

[ #31001 ]

Today I was in a different sort of mood. I decided to play with some Haskell, and ended up with the following. I started with a recursive function in Haskell which computes products:

product [] = 1
product (x:xs) = x * product xs

I then decided to write the same functionality in Perl 5 and Perl 6 to see how they compared. Along the way I ran into reduction operators, which turn out to appear in some form in all three languages, although I have never used them in any. Here's the function looks lik all three languages. I provide the print statement in only one case, since it is basically the same in all three:

-- Haskell
prod = foldr (*) 1

# Perl 5
use List::Util qw(reduce);
sub prod { reduce { $a * $b } 1, @_ }

# Perl 6
sub prod (*@xs) { [*] @xs }
print prod(2,3,4);

Not only does the Haskell solution look the cleanest to me, it was the only language I didn't find a related bug in. I added tests for [*]() and [+](), which are not yet returning 1 and 0 as expected in Pugs.

It turns out perl5 List::Util::sum() was returning "undef" for a empty lists instead of 0. I submitted a patch for that.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • Not only does the Haskell solution look the cleanest to me...

    Only because you didn't do it as cleanly as you could have. :-)

    A fairer comparison would be:

    -- Haskell
    prod = foldr (*) 1

    # Perl 6
    sub prod { [*] @_ }

    Or, if you prefer the equals sign:

    -- Haskell
    prod  = foldr (*) 1

    # Perl 6
    &prod := sub{ [*] @_ }

    Damian

    • Can that last one be written with the -> op?

      • Yes, in this case it can. You could write:
        # Perl 6
        &prod := -> *@list { [*] @list }
        which isn't exactly pretty, but does at least include a smiley face. ;-)

        Damian