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

Bengt Richter bokr at oz.net
Tue Jun 4 18:11:27 EDT 2002


On 4 Jun 2002 17:51:15 GMT, "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.
>
>|> 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.
>
But see below...

>| ... 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.
>
>...
>| 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.
>

Here is a contrived case where += lets you use a
mutable-lhs-target-expression-with-side-effect and
get only one side effect. There are obviously other
ways, but at least += is convenient (and presumably
faster in a case like this).

 >>> a=[0]
 >>> def foo():
 ...     print 'side effect'
 ...     return a
 ...
 >>> foo()
 side effect
 [0]
 >>> foo()[0]+=1
 side effect
 >>> a
 [1]
 >>> foo()[0] = foo()[0]+1
 side effect
 side effect
 >>> a
 [2]

Regards,
Bengt Richter



More information about the Python-list mailing list