Skip Menu |

This queue is for tickets about the Scalar-List-Utils CPAN distribution.

Report information
The Basics
Id: 21505
Status: resolved
Priority: 0/
Queue: Scalar-List-Utils

People
Owner: Nobody in particular
Requestors: MARKSTOS [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 1.18
Fixed in: (no value)



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
Subject: Re: [rt.cpan.org #21505] sum() should return zero, not undef
Date: Fri, 15 Sep 2006 08:11:01 -0500 (CDT)
To: bug-Scalar-List-Utils [...] rt.cpan.org
From: "Graham Barr" <gbarr [...] pobox.com>
On Thu, September 14, 2006 9:00 pm, via RT wrote: Show quoted text
> 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.
This is not a bug. sum() was around a long time before perl6 and has always been defined to return undef for zero arguments Graham.
Subject: Re: [rt.cpan.org #21505] sum() should return zero, not undef
Date: Fri, 15 Sep 2006 09:49:33 -0400
To: bug-Scalar-List-Utils [...] rt.cpan.org
From: Mark Stosberg <mark [...] summersault.com>
Graham, Graham Barr via RT wrote: Show quoted text
> <URL: http://rt.cpan.org/Ticket/Display.html?id=21505 > > > On Thu, September 14, 2006 9:00 pm, via RT wrote:
>> 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.
> > This is not a bug. sum() was around a long time before perl6 and has > always been defined to return undef for zero arguments
Thank you for the prompt response. I could agree that it's not a bug in the sense that the software behaves as it is documented. I also understand your possible reluctance as a maintainer to change something in an incompatible way. My suggestion then was more about a bug in the sense of mathematical correctness, which the Perl 6 spec happens to implement. Returning zero does seem more useful, as the sum of an empty list might appear as a case in a larger formula, where "0" works directly, and "undef" needs to be translated to zero if appears. I would certainly respect your decision if you chose to maintain compatibility, since the return value of undef has been clearly documented. Mark
Subject: Re: [rt.cpan.org #21505] sum() should return zero, not undef
Date: Fri, 15 Sep 2006 13:44:40 -0500 (CDT)
To: bug-Scalar-List-Utils [...] rt.cpan.org
From: "Graham Barr" <gbarr [...] pobox.com>
On Fri, September 15, 2006 8:51 am, mark@summersault.com via RT wrote: Show quoted text
> I could agree that it's not a bug in the sense that the software behaves > as it is documented. I also understand your possible reluctance as a > maintainer to change something in an incompatible way.
I have had this discussion many times in the past. If your algorithm requires zero as an identity, then use sum(0,@values), but if you have and algorithm that requires to know the difference of sum(foobar()) when foobar() returns () or (0) then undef makes more sense. Basically may argument is that the current implementation is more flexable as it can solve both situations. makeing sum() return zero cannot. Graham.
Subject: Re: [rt.cpan.org #21505] sum() should return zero, not undef
Date: Fri, 15 Sep 2006 15:28:13 -0400
To: bug-Scalar-List-Utils [...] rt.cpan.org
From: Mark Stosberg <mark [...] summersault.com>
Graham Barr via RT wrote: Show quoted text
> <URL: http://rt.cpan.org/Ticket/Display.html?id=21505 > > > On Fri, September 15, 2006 8:51 am, mark@summersault.com via RT wrote:
>> I could agree that it's not a bug in the sense that the software behaves >> as it is documented. I also understand your possible reluctance as a >> maintainer to change something in an incompatible way.
> > I have had this discussion many times in the past. If your algorithm > requires zero as an identity, then use sum(0,@values), but if you have > and algorithm that requires to know the difference of sum(foobar()) when > foobar() returns () or (0) then undef makes more sense. > > Basically may argument is that the current implementation is more flexable > as it can solve both situations. makeing sum() return zero cannot.
That's reasonable. I suggest adding a little something to the docs to put to end to people bringing it up then, including the sub(0,@values) example. From reviewing the docs, tests and code comments, I saw no indications it has been considered, so it looked like an oversight. Thanks for maintaining this module, Graham. It has some useful functions it, and I appreciate people who can write ".xs" modules, since it's not a skill I have myself. Mark
The following has been added to the documentation for sum() If your algorithm requires that C<sum> produce an identity of 0, then make sure that you always pass C<0> as the first argument to prevent C<undef> being returned $foo = sum 0, @values; Similar text has also been added to reduce Graham.