Reseatable references (programming)

Aug 18, 2010 16:08

Oops.

In Python, a += b is *not* always equivalent to a = a + b.

Fortunately, I caught it fairly quickly.

Leave a comment

Comments 10

bateleur August 18 2010, 17:08:30 UTC
Out of interest, why not?

Reply

onebyone August 18 2010, 17:13:30 UTC
Because a += b modifies the referand of a, whereas a = a + b creates a new object and binds it to a.

So for example:
$ python
Python 2.6.5 (r265:79063, Jun 12 2010, 17:07:01)
[GCC 4.3.4 20090804 (release) 1] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = [1,2]
>>> b = [3,4]
>>> c = a
>>> a += b
>>> c
[1, 2, 3, 4]
>>> a = a + b
>>> c
[1, 2, 3, 4]
>>> a
[1, 2, 3, 4, 3, 4]

This probably shouldn't surprising except to C and C++ programmers...

Reply

bateleur August 18 2010, 17:21:58 UTC
I don't know about surprising, but I wouldn't expect it necessarily.

From my perspective it's non-intuitive to use += syntax for left hand sides that might not be mutable. And equally, expecting a = a + b to always bind a new object is no good, because not all left hand sides are bindable.

For example, a = a + b in JavaScript is mutation if a is a Number but is binding if a is a String.

Reply

onebyone August 18 2010, 17:45:27 UTC
Well, in Python everything is objects (semantically), so assignment with '=' is always binding, never mutation even for numbers. But I didn't give you the whole story above: += mutates only if the type permits (I don't know precisely how that's defined at the language level). Both numbers and strings are immutable, so for Python in both your examples a += b doesn't mutate, it does the same as a = a + b.

Python lists are mutable, and += behaves like extend().

I suppose really it's the combination of reseatable references with mutable objects that creates two possible meanings of +=, and hence the opportunity for surprise.

Reply


Leave a comment

Up