Reduction operators

markjugg on 2006-09-15T02:59:21

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.


Let's be fair...

Damian on 2006-09-15T11:35:03

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

Re:Let's be fair...

Aristotle on 2006-09-15T15:12:16

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

Re:Let's be fair...

Damian on 2006-09-16T14:46:13

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