One last shot at the Augmented Assignment PEP

Alex Martelli aleaxit at yahoo.com
Thu Sep 14 13:22:04 CEST 2000


"Bob Alexander" <balexander at rsv.ricoh.com> wrote in message
news:39C02BFB.24B72258 at rsv.ricoh.com...
    [snip]
> you change your example a bit:
>
>      a = aa = copy(x)
>      b = bb = copy(x)
>      a = a + y
>      b += y
>      assert a==b # succeeds
>      assert aa==bb # fails

Let's change this a little bit further...:

   a = aa = copy(x)
   b = bb = copy(x)
   a = a.make_a_new_widget_by_adding(y)
   try:
       b.mutate_this_widget_by_adding(y)
   except AttributeError:
       b = b.make_a_new_widget_by_adding(y)

   assert a==b # succeeds
   assert aa==bb # fails -- or doesn't!

*THIS* very important idiom is what += is syntax
sugar for, in Python.

> it seems wrong to me that there is a non-obvious side effect that
> modifies bb. (You might have had to look twice to notice that.) And it

This observation applies to ALL mutating-methods.  If you're
serious about seeing this as a problem, I suggest you look
into Haskell, where no object is mutable (pay no attention to
the monad behind the curtain).  In Python, mutable objects are
first-class (just as immutable ones): this is a crucial issue.

If you care about other references being unaffected, you must
always explicitly copy.copy() [sometimes copy.deepcopy()] the
object before calling on it methods that may mutate it.  For
really effective use of Python, these issues MUST be well
understood.  If += and friends thrust them to prominence, I'm
quite happy with that, because they need and deserve such
prominence.

> only applies to the second form, even though their appearance could fool
> one into thinking they do the same thing. aa was untouched, an one would
> expect of concatenation and assignment (or rebinding, or whatever you
> like to call it).

I would NOT expect a mutable object to be left untouched by a
possibly-mutating method.  For example, if the object is a
matrix of a million cells, I would NOT expect a copy of the
matrix's original value to be kept, in Python, if I do:
    m += 1.0
to add 1.0 to each element.

And I'm quite comfortable with += defaulting to a *mutating*
operation if it possibly can, and falling back to non-mutation
and rebinding if needed (because mutation is not feasible).
To me, it *looks* like += and friends are *asking* the object
to mutate; the polymorphic fallback when the object won't
comply with that request makes it all smooth and usable.  And
thereby extremely Pythonic and elegant.


> > ... += and its ilk would be mere syntactic sugar of no big real
interest.
>
> I agree that += would be "mere" syntactic sugar, but I disagree that it
> is of no big interest. It can reduce the labor of writing and the
> clarity of reading, and that is of very real interest to me. Oddly,
> syntactic sugar can make programs actually *lose* weight!

If you know you're dealing with immutable objects, such as numbers,
strings, tuples, you can use += exactly as you wish.  Having an
object that is mutable (or whose mutability is unknown), and NOT
wishing to mutate it (or risking mutation), is a rarer case, and
requires more runtime work.  I love the fact that += and friends
are optimized for the common cases -- where I'm quite willing to
mutate the object, if it's mutable.  When you DO want that extra
work to be performed, be explicit about it, as you were until now:
    x = x + 1
and it won't be that much skin off your nose!  Meanwhile, in the
common case where mutation IS quite allright if feasible (and thus
desirable for efficiency reasons), as well as the reasonably
frequent case where you know you're dealing with immutables,
    x += 1
will do the right thing.


> I don't think it is important or desirable to try to make augmented
> assignment "more interesting" by introducing these additional semantics
> that don't fit the expectation of assignment.

They do fit the expectations that 'assignment' carries in languages
where CALLING it 'assignment' really makes sense, such as Fortran,
C, C++.  Languages with a semantics of binding (rather than actual
assignment) would, IMHO, be better off calling it binding.

I think it's EXTREMELY important and desirable to allow this natural
use of operators to have the most usually desirable semantics, in
particular for numeric computations (possibly on big matrices &c),
where the use of +, *, etc, is really widespread and important.


> Is it really too late to change this? 2.0 isn't final yet.

It's fortunately too late (not that there's any risk of this
ever disappearing again, I should hope).


Alex






More information about the Python-list mailing list