Behavior of += (was Re: [Python-Dev] Customization docs)

Steve Holden sholden at holdenweb.com
Tue Jun 4 16:32:16 EDT 2002


"Donn Cave" <donn at u.washington.edu> wrote ...
> Quoth Chris Barker <Chris.Barker at noaa.gov>:
> | Huaiyu Zhu wrote:
> |> Great explanation!  The problem stems from the fact that the current +=
> |> operator implements two semantically distinct operations, chosen
according
> |> to some properties of the operands.
> |
> | exactly, and it wa kind of a weird decision. Personally, I feel the only
> | compelling reason to add The += (and friends) operator was to support
> | in-place addition, most notably for Numeric arrays. Frankly it ought to
> | just be disallowed for non-mutable types, but all the folks that want it
> | for integers would scream. to be honest, I've kind of lost track of why
> | it is a good idea for numbers to be immutable, but that's another topic!
>
> That would be almost as cool as the old implementations of FORTRAN
> where you could change the value of 1.
>
Don't you mean "...change the value of True" <wink>?

> |> I'd imagine that at some future time there would be a desire to split
+= to
> |> two distinct operators, one for true in-place operator and one for the
fake
> |> one currently implemented for immutables.  That would remove the
spurious
> |> exceptions for mutable members of immutable structures.
> |
> | Do we really need a new notation? is a = a + b so bad?
>
> No, it's fine.
>
> | ... In fact, are the
> | current semantics of += s bad, or should this bug just be fixed?
>
> Not really - the current semantics are actually better than the fixed
> version, inasmuch as they are at least consistent.  As I interpret the
> proposal, the fixed += would sometimes work without rebinding (if the
> object supports it) and sometimes would be an assignment (falling back
> to +.)  To me, to allow an object to dictate its relationship to its
> computational environment like that is anathema.
>
>>> a = b = (1, 2, 3)
>>> a += ('boo!',)
>>> a, b
((1, 2, 3, 'boo!'), (1, 2, 3))
>>> a = b = [1, 2, 3]
>>> a += ['boo!']
>>> a, b
([1, 2, 3, 'boo!'], [1, 2, 3, 'boo!'])

Doesn't look that consistent to me. Add in the fact that implementors of
mutable objects are free to choose either semantic and what you have is ...
exactly what Guido intended. I regard it as a wart, but not one that worried
me.

> ...
> | By the way, the += and friends operators also cause similar confusion
> | with name scopes in functions, += is assumed to be a re-bind, when it
> | isn't necessarily intended to:
> |
> | >>> l = [1,2,3]
> | >>> def test():
> | ...     l += [4]
> | ...
> | >>> test()
> | Traceback (most recent call last):
> |   File "<stdin>", line 1, in ?
> |   File "<stdin>", line 2, in test
> | UnboundLocalError: local variable 'l' referenced before assignment
> |
> | but:
> |
> | >>> def test2():
> | ...     l.extend([4])
> |
> | >>> test2()
> | >>> l
> | [1, 2, 3, 5]
> |
> | Works just fine. Perhaps  Huaiyu is right, we need different operators.
> | However, then the operator for incrementing a non-mutable would just be
> | a synonym for a = a + b, which looks like unnecessary syntactical sugar
> | to me.
>
> Yes.
>
Warts are warts. If only Guido had listened to me ... :-)

quite-glad-really-it's-someone-else's-fault-ly y'rs  - steve
--
-----------------------------------------------------------------------
Steve Holden                                 http://www.holdenweb.com/
Python Web Programming                http://pydish.holdenweb.com/pwp/
-----------------------------------------------------------------------








More information about the Python-list mailing list