Velocity Reviews > Re: restriction on sum: intentional bug?

# Re: restriction on sum: intentional bug?

Steve
Guest
Posts: n/a

 10-27-2009
On Oct 17, 8:28*pm, Tim Chase <(E-Mail Removed)> wrote:
> Christian Heimes wrote:
> > Alan G Isaac wrote:
> >> On 10/16/2009 5:03 PM, Christian Heimes wrote:
> >>> It's not going to happen.
> >> That's a prediction, not a justification.

>
> > It's not a prediction, it's a statement. It's not going to happend
> > because it violates Guido's gut feeling as well as the Zen of Python.

>
> I'm not sure how it violates ZoP...particularly
>
> Simple is better than complex.
> * *[complex is special casing or explaining why there's an error]
> Special cases aren't special enough to break the rules.
> * *[raising an error is a special case]
> Although practicality beats purity.
> In the face of ambiguity, refuse the temptation to guess.
> * *[there's nothing ambiguous about sum() meaning "+"]
> If the implementation is easy to explain, it may be a good idea.
> * *[sum(lst_of_strs) should do exactly what it says..."+" 'em]
>
> -tkc

You overlooked "There should be one-- and preferably only one --
obvious way to do it.", which in this case is join()

To me the current implementation is blatantly correct. sum is an
operation on a list of numeric values, returning a numeric value -
this is why we have the seemingly strange "".join() rather than [].join
("")

I think duck typing is wonderful so long as its specific applications
make sense. We don't handle integers being passed to len() do we?
Technically we could return the number of digits but it wouldn't make
sense as len() works on iterables.

Luis Zarrabeitia
Guest
Posts: n/a

 10-27-2009
On Tuesday 27 October 2009 07:29:46 am Steve wrote:
> To me the current implementation is blatantly correct. sum is an
> operation on a list of numeric values, returning a numeric value -
> this is why we have the seemingly strange "".join() rather than [].join
> ("")

But then, why does sum() accept non-numeric input? How does sum decides if the
arguments are "numbers", given that it accepts almost everything that defines

I really never tried to sum() strings before, but it makes sense that, if
sum() already checks if the argument is a string before, it should do
the "".join instead of returning an error.

Also, why is there a special case for the strings, but not for the tuples?
Doesn't sum(((1,) for _ in xrange(100)),()) also have quadratic behaviour,
creating and destroying intermediate tuples? And what happens with lists?

--
Luis Zarrabeitia (aka Kyrie)
Fac. de Matemática y Computación, UH.
http://profesores.matcom.uh.cu/~kyrie

Ethan Furman
Guest
Posts: n/a

 10-27-2009
Steve wrote:
> On Oct 17, 8:28 pm, Tim Chase <(E-Mail Removed)> wrote:
>
>>Christian Heimes wrote:
>>
>>>Alan G Isaac wrote:
>>>
>>>>On 10/16/2009 5:03 PM, Christian Heimes wrote:
>>>>
>>>>>It's not going to happen.
>>>>
>>>>That's a prediction, not a justification.

>>
>>>It's not a prediction, it's a statement. It's not going to happend
>>>because it violates Guido's gut feeling as well as the Zen of Python.

>>
>>I'm not sure how it violates ZoP...particularly
>>
>>Simple is better than complex.
>> [complex is special casing or explaining why there's an error]
>>Special cases aren't special enough to break the rules.
>> [raising an error is a special case]
>>Although practicality beats purity.
>>In the face of ambiguity, refuse the temptation to guess.
>> [there's nothing ambiguous about sum() meaning "+"]
>>If the implementation is easy to explain, it may be a good idea.
>> [sum(lst_of_strs) should do exactly what it says..."+" 'em]
>>
>>-tkc

>
>
>
> You overlooked "There should be one-- and preferably only one --
> obvious way to do it.", which in this case is join()

That doesn't mean *only* one obvious way to do it, and more importantly
it *does not* mean *only one way* to do it.

> To me the current implementation is blatantly correct. sum is an
> operation on a list of numeric values, returning a numeric value -
> this is why we have the seemingly strange "".join() rather than [].join
> ("")
>
> I think duck typing is wonderful so long as its specific applications
> make sense.

Duck typing is about not guessing what will make sense, or what needs
will arise, to the users of our code.

> We don't handle integers being passed to len() do we?
> Technically we could return the number of digits but it wouldn't make
> sense as len() works on iterables.

Ints do not have a __len__ method, so why should len() work on them?
Strs, on the other hand, do have an __add__ method.

~Ethan~

Steven D'Aprano
Guest
Posts: n/a

 10-27-2009
On Tue, 27 Oct 2009 05:29:46 -0700, Steve wrote:

> To me the current implementation is blatantly correct. sum is an
> operation on a list of numeric values, returning a numeric value - this
> is why we have the seemingly strange "".join() rather than [].join ("")

That is absolutely wrong. sum() works on anything with an __add__ method,
including lists, tuples, and even strings provided you defeat the hand-
holding the function does:

>>> sum(["a", "b"], '')

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: sum() can't sum strings [use ''.join(seq) instead]
>>>
>>> class Helper:

.... return other
....
>>> sum(["a", "b"], Helper())

'ab'

> I think duck typing is wonderful so long as its specific applications
> make sense. We don't handle integers being passed to len() do we?
> Technically we could return the number of digits but it wouldn't make
> sense as len() works on iterables.

The number of digits in what base?

len() works on anything with a __len__ method. Not all iterables have a
known length. The most important examples are iterators and generators:

>>> len(iter('a'))

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'iterator' has no len()

And there's no guarantee that an object with __len__ is iterable:

>>> class Weird:

.... def __len__(self):
.... return 42
....
>>> len(Weird())

42
>>> list(Weird())

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: iteration over non-sequence

Admittedly it is an abuse of len() to create an non-iterable object with
__len__, but you can do it.

Personally, I think that sum() should, at most, just emit a warning if
you pass a string as the second argument. Anything more than that is
needlessly nanny-like. Python let's you shoot yourself in the foot if you
like, I don't see that the consequences of summing strings is so harmful
that it needs to be exceptional. But apparently Guido disagrees, and so
the behaviour will stay.

--
Steven