I'm using rather often List::Util lately. I noticed that sum returns undef on an empty list:

$ perl -w -MList::Util=sum -le 'print sum' Use of uninitialized value in print at -e line 1.

Mathematically, it makes much more sense to return 0. Failing to do so forces me to either || 0 or use no warnings 'uninitialized'; and I wonder whether changing its behaviour is likely to break anything, although that seems highly improbable to me.

Replies are listed 'Best First'.
Re: List::Util::sum() and empty lists...
by BrowserUk (Patriarch) on Dec 03, 2006 at 15:14 UTC

    I'm not saying it's the right solution in the long term, but you can avoid the problem by always passing a constant zero as the first argument to sum. It has no affect upon the result, but does the right thing if the rest of the list is empty.

    print sum 0, ();; 0

    Similarly, passing a constant 1 as the first term to reduce if your using it to calculate product(), and the appropriate identity as the first term for other operations avoids the need for tests, or the generation of warnings.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Yeah, the Ruby way to do this is to use inject and pass the appropriate seed value for the operation. If you don't like the explicitness there you can always hide it by extending Enumerable yourself.

      module Enumerable def sum( ) inject( 0 ) { |m,x| m += x } ; end def prod( ) inject( 1 ) { |m,x| m *= x } ; end end

      Additionally: As to the original question (changing to return 0 by default), you kind of loose information that way in that you don't know if you had an empty list versus having a list which just happened to sum to zero. Of course you could always explicitly check for that (presuming you have the original list around) if you needed to know. (So chalk this up as a wishy washy non-comittal neither condemnation nor approval of the proposal. :)

      I'm not saying it's the right solution in the long term, but you can avoid the problem by always passing a constant zero as the first argument to sum. It has no affect upon the result, but does the right thing if the rest of the list is empty.

      Nice trick (albeit still a trick) BrowserUk++, I must admit that simple and intuitive as it is, I hadn't thought about it: it's much lighter than say || 0, also having the big advantage of not creating problems with precedences and such.

Re: List::Util::sum() and empty lists...
by Firefly258 (Beadle) on Dec 04, 2006 at 11:12 UTC
    Mathematically, it makes much more sense to return 0.

    Yes but logically (and mathematically too), the sum of an undefined list ought to be an undefined value, don't you think?

    sum() returning undef or 0 helps discern whether the argument list passed to it was an empty one or not.

    $ perl -MList::Util=sum -Wle 'printf "sum returns [%s]", sum()' Use of uninitialized value in printf at -e line 1. sum returns [] $ perl -MList::Util=sum -Wle 'printf "sum returns [%s]", sum(undef) Use of uninitialized value in subroutine entry at -e line 1. sum returns [0]


    perl -e '$,=$",$_=(split/\W/,$^X)[y[eval]]]+--$_],print+just,another,split,hack'er
      the sum of an undefined list ought to be an undefined value

      The empty list is not undefined; it's very clearly defined: it's empty.

      Speaking as a mathematician, of course the sum of an empty list is 0, but this is hardly the first nor the most important time I've encountered software that doesn't follow mathematical conventions. Regardless, the sum 0, @list fix is completely fine.

      A reply falls below the community's threshold of quality. You may see it by logging in.