Ram Rachum wrote:
I prefer (b). The problem with requiring `start` for sequences of non-numerical objects is that you now have to go out and create a "zero object" of the same type as your other objects. The object class might not even have a concept of a "zero object".
class _AdditiveIdentity(object): def __add__(self, other): return other __radd__ = __add__
AdditiveIdentity = _AdditiveIdentity()
total = sum(itr, start=AdditiveIdentity) if total is AdditiveIdentity: # Iterable was empty else: # we got a real result
(Raymond already posted along these lines, but I wanted to point out that by making the identity object a singleton you can save the cost of repeated instantiation and simplify the after-the-fact check for an empty iterable)
The other philosophical point here is one Guido has expressed several times in the past: "In general, the type of a return value should not depend on the *value* of an argument" (although the different numeric types tend to blur together a bit in this specific context)
With only a default value, sum() could return entirely different types based on whether or not the sequence was empty.
With a start value, on the other hand, the type returned must at least be one that is compatible under addition with the start value. You can subvert that a bit through the use of a universal additive identity, but it holds short of that.