[Python-Dev] Re: [Python-checkins] python/dist/src/Python bltinmodule.c, 2.292.10.1, 2.292.10.2

Armin Rigo arigo at tunes.org
Sun Oct 26 14:37:55 EST 2003


Hello Alex,

On Sun, Oct 26, 2003 at 07:20:52PM +0100, Alex Martelli wrote:
> > def sum(seq, start=0):
> >   for item in seq:
> >     start = start + seq
> >   return start
> 
> It IS equivalent to that -- plus an explicit typetest to raise if start is an
> instance of str or unicode.

Yes, it is what I'm saying: it is what we expect it to be, but there is an
exception for no real reason apart from "don't do it like this, buddy, there
is a faster version out there".

I tend to regard this kind of exceptions as very bad, because if you write a
generic algorithm using sum(), even if you don't really see why someone would
think about using your algorithm with strings one day, chances are that
someone will.

Raising a Warning instead of an exception would have had the same result
without the generality problem.

> >   reduce(operator.add, seq, start)
> 
> sum doesn't reproduce reduce's quirk of using the first item of seq if start
> is not given.  So, the def version is closer.

I was thinking about:

  def sum(seq, start=0):
    return reduce(operator.add, seq, start)

which is the same as the previous one.

> Admittedly the latter version may accept a few more cases, e.g.
> both versions would accept:
>     sum([ range(3), 'foo' ], [])
> because [] is copyable, []+range(3) is fine, and list.__iadd__ is
> more permissive than list.__add__; however, the first version 
> would fail on:
>     sum([ 'foo', range(3) ], [])
> because []+'foo' fails, while the second version would be fine
> because [] is _still_ copyable and __iadd__ is still permissive:-).

These cases all show that we have a surprize problem (although probably not a
big one).  The user will expect sum() to have a clean definition, and because
the += one doesn't work, it must be +.  To my opinion, sum() should be
strictly equivalent to the naive + version and try to optimize common cases
under the hood.

Admittedly, this is not obvious, because of precisely all these strange mixed 
type cases which could be user-defined classes with __add__ or __radd__ 
operators...

I'm sure someone will design a class

class x:
  def __add__(self, other):
    return other

so that x() can be used as a trivial starting point for sum() -- and
then sum(["abc", "def"], x()) works :-)


Armin




More information about the Python-Dev mailing list