Subject: | sum() should return zero, not undef |
The correct answer for sum() is 0. This is part of the
Perl 6 spec ([+]() == 0) and is explained here:
http://haskell.org/hawiki/BaseCasesAndIdentities.
The attached complete patch fixes the tests, docs, code and ChangeLog.
Please peer review the XS code, though-- I guessed!
I attached a second patch which clarifies the related situation for
finding a product by reduction. "1", not undef, should be returned in
that case if there is a empty list.
Mark
Subject: | sum.patch |
Thu Sep 14 21:48:29 EST 2006 mark@summersault.com
* sum() with no args should return zero, not undef.
This is explained here: http://haskell.org/hawiki/BaseCasesAndIdentities
And also reflected in the Perl 6 spec, which says that [+]() should return zero.
diff -rN -u old-Scalar-List-Utils-1.18/Changes new-Scalar-List-Utils-1.18/Changes
--- old-Scalar-List-Utils-1.18/Changes 2006-09-14 21:50:41.000000000 -0500
+++ new-Scalar-List-Utils-1.18/Changes 2006-09-14 21:50:41.000000000 -0500
@@ -1,3 +1,6 @@
+Bug Fixes
+ * sum() should return 0, not undef. (Mark Stosberg)
+
1.18 -- Fri Nov 25 09:30:29 CST 2005
Bug Fixes
diff -rN -u old-Scalar-List-Utils-1.18/lib/List/Util.pm new-Scalar-List-Utils-1.18/lib/List/Util.pm
--- old-Scalar-List-Utils-1.18/lib/List/Util.pm 2006-09-14 21:50:41.000000000 -0500
+++ new-Scalar-List-Utils-1.18/lib/List/Util.pm 2006-09-14 21:50:41.000000000 -0500
@@ -77,7 +77,7 @@
use vars qw($a $b);
-sub sum (@) { reduce { $a + $b } @_ }
+sub sum (@) { reduce { $a + $b } 0, @_ }
sub min (@) { reduce { $a < $b ? $a : $b } @_ }
@@ -209,7 +209,7 @@
$foo = reduce { $a < $b ? $a : $b } 1..10 # min
$foo = reduce { $a lt $b ? $a : $b } 'aa'..'zz' # minstr
- $foo = reduce { $a + $b } 1 .. 10 # sum
+ $foo = reduce { $a + $b } 0, 1 .. 10 # sum
$foo = reduce { $a . $b } @bar # concat
=item shuffle LIST
@@ -221,7 +221,7 @@
=item sum LIST
Returns the sum of all the elements in LIST. If LIST is empty then
-C<undef> is returned.
+C<0> is returned.
$foo = sum 1..10 # 55
$foo = sum 3,9,12 # 24
@@ -229,7 +229,7 @@
This function could be implemented using C<reduce> like this
- $foo = reduce { $a + $b } 1..10
+ $foo = reduce { $a + $b } 0, 1..10
=back
diff -rN -u old-Scalar-List-Utils-1.18/t/sum.t new-Scalar-List-Utils-1.18/t/sum.t
--- old-Scalar-List-Utils-1.18/t/sum.t 2006-09-14 21:50:41.000000000 -0500
+++ new-Scalar-List-Utils-1.18/t/sum.t 2006-09-14 21:39:53.000000000 -0500
@@ -18,7 +18,7 @@
use List::Util qw(sum);
my $v = sum;
-is( $v, undef, 'no args');
+is( $v, 0, 'no args');
$v = sum(9);
is( $v, 9, 'one arg');
diff -rN -u old-Scalar-List-Utils-1.18/Util.xs new-Scalar-List-Utils-1.18/Util.xs
--- old-Scalar-List-Utils-1.18/Util.xs 2006-09-14 21:50:41.000000000 -0500
+++ new-Scalar-List-Utils-1.18/Util.xs 2006-09-14 21:40:32.000000000 -0500
@@ -174,7 +174,7 @@
SV *sv;
int index;
if(!items) {
- XSRETURN_UNDEF;
+ RETVAL = 0;
}
sv = ST(0);
RETVAL = slu_sv_value(sv);
Subject: | product.patch |
Thu Sep 14 21:49:26 EST 2006 mark@summersault.com
* explain correct return value for using reduce to compute the product of an empty list
diff -rN -u old-Scalar-List-Utils-1.18/Changes new-Scalar-List-Utils-1.18/Changes
--- old-Scalar-List-Utils-1.18/Changes 2006-09-14 21:50:53.000000000 -0500
+++ new-Scalar-List-Utils-1.18/Changes 2006-09-14 21:49:20.000000000 -0500
@@ -1,3 +1,4 @@
+
Bug Fixes
* sum() should return 0, not undef. (Mark Stosberg)
diff -rN -u old-Scalar-List-Utils-1.18/lib/List/Util.pm new-Scalar-List-Utils-1.18/lib/List/Util.pm
--- old-Scalar-List-Utils-1.18/lib/List/Util.pm 2006-09-14 21:50:53.000000000 -0500
+++ new-Scalar-List-Utils-1.18/lib/List/Util.pm 2006-09-14 21:47:53.000000000 -0500
@@ -212,6 +212,11 @@
$foo = reduce { $a + $b } 0, 1 .. 10 # sum
$foo = reduce { $a . $b } @bar # concat
+Note that if you are using C<reduce> to compute a product, it is correct
+to return 1 if there are no arguments:
+
+ $foo = reduce { $a * $b } 1, @nums # product
+
=item shuffle LIST
Returns the elements of LIST in a random order