User-defined augmented assignment

2005-09-29 Thread Pierre Barbier de Reuille
Hello,

a discussion began on python-dev about this. It began by a bug report,
but is shifted and it now belongs to this discussion group.

The problem I find with augmented assignment is it's too complex, it's
badly explained, it's error-prone. And most of all, I don't see any
use-case for it !

The most common error is to consider that :

 a += b <==> a.__iadd__(b)

when the truth is :

 a += b <==> a = a.__iadd__(b)

which can be very confusing, as the two "a" are not necessarily the
same. It then leads to subtle errors like:

>>> class A(object):
>>>   a = 0

>>> a = A()
>>> b = A()
>>> a.a += 1
>>> A.a += 2
>>> print a.a
1
>>> print b.a
2

Also, the following behavior is pretty confusing :

>>> a = [1]
>>> b = [a]
>>> c = (a,)
>>> b[0] += [2] # Ok, no pb
>>> print a
[1,2]
>>> c[0] += [3]
Traceback (most recent call last):
  File "", line 1, in ?
TypeError: object doesn't support item assignment
>>> print a
[1,2,3]

Then, in the standard library, there is no use-case of user-defined
augmented assignment I could find. Of course, I find the augmented
assignement itself very useful ! I use it a lot with immutable objects
(strings, numbers, tuples, ...) but I tend to avoid it with mutables,
and so it seems in the standard library that uses extensively the
"extend" method of lists and very seldom the "+=" operator with lists.
And even where the "a+=b" is used, it could be replaced with either
"a.extend(b)" or "a = a+b" without bugs.

So, what I would suggest is to drop the user-defined augmented
assignment and to ensure this equivalence :

a X= b <=> a = a X b

with 'X' begin one of the operators.

Pierre
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: User-defined augmented assignment

2005-10-01 Thread Tom Anderson
On Thu, 29 Sep 2005, Pierre Barbier de Reuille wrote:

> a discussion began on python-dev about this. It began by a bug report, 
> but is shifted and it now belongs to this discussion group.
>
> The problem I find with augmented assignment is it's too complex, it's
> badly explained, it's error-prone. And most of all, I don't see any
> use-case for it !
>
> The most common error is to consider that :
>
> a += b <==> a.__iadd__(b)
>
> when the truth is :
>
> a += b <==> a = a.__iadd__(b)
>
> which can be very confusing, as the two "a" are not necessarily the
> same.

Indeed. I certainly didn't realise that was how it worked.

> So, what I would suggest is to drop the user-defined augmented 
> assignment and to ensure this equivalence :
>
> a X= b <=> a = a X b
>
> with 'X' begin one of the operators.

That seems quite an odd move. Your proposal would lead to even more 
surprising behaviour; consider this:

a = [1, 2, 3]
b = a
a += [4, 5, 6]
print b

At present, this prints [1, 2, 3, 4, 5, 6]; if we were to follow your 
suggestion, it would be [1, 2, 3].

So, -1, i'm afraid.

I think the right solution here is staring us in the face: if everyone 
seems to think that:

a += b <==> a.__iadd__(b)

Then why not make it so that:

a += b <==> a.__iadd__(b)

Principle of Least Surprise and all that.

Since not everything that should support += is mutable (integers, for 
example), how about saying that if the recipient of a += doesn't have an 
__iadd__ method, execution falls back to:

a = a + b

I say 'a + b', because that means we invoke __add__ and __radd__ 
appropriately; indeed, the __add__ vs __radd__ thing is a precedent for 
this sort of fallback.

Doesn't that leave everyone happy?

tom

-- 
I'm not quite sure how that works but I like it ...
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: User-defined augmented assignment

2005-09-29 Thread Reinhold Birkenfeld
Pierre Barbier de Reuille wrote:

> So, what I would suggest is to drop the user-defined augmented
> assignment and to ensure this equivalence :
> 
> a X= b <=> a = a X b
> 
> with 'X' begin one of the operators.

It can be done, but it's unnecessary for mutable objects like
sets or lists. A new object must be created in these cases where
one would suffice.

Reinhold
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: User-defined augmented assignment

2005-09-29 Thread Pierre Barbier de Reuille
Reinhold Birkenfeld a écrit :
> Pierre Barbier de Reuille wrote:
> 
> 
>>So, what I would suggest is to drop the user-defined augmented
>>assignment and to ensure this equivalence :
>>
>>a X= b <=> a = a X b
>>
>>with 'X' begin one of the operators.
> 
> 
> It can be done, but it's unnecessary for mutable objects like
> sets or lists. A new object must be created in these cases where
> one would suffice.

Well, my point is: the benefit is too small compared to the
disadvantage. If you really have a mutable (let say a list with +=) then
you do:

>>> a.extend(b)

and there is no interpretation error possible. BTW, that's what's done
in the standard library ...

Pierre

> 
> Reinhold
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: User-defined augmented assignment

2005-09-29 Thread Paddy
I thought along these lines:
  It is an augmented ASSIGNMENT. (It even has an equals sign in it).
  tuples are immutable so you should not be able to assign to one of
its elements.

 - So there is no problem for me - I shouldn't be messing with an
element of an
immutable type!

- Cheers, Paddy.

-- 
http://mail.python.org/mailman/listinfo/python-list