Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have no idea what these are actually called, but I see them all the time. The Python implementation is something like:

x += 5 as a shorthand notation for x = x + 5.

But why is this considered good practice? I've run across it in nearly every book or programming tutorial I've read for Python, C, R so on and so forth. I get that it's convenient, saving 3 keystrokes including spaces. But they always seem to trip me up when I'm reading code, and at least to my mind, make it less readable, not more.

Am I missing some clear and obvious reason these are used all over the place?

share|improve this question
6  
@blesh: That small details of how one expresses an addition in source code have an impact on efficiency of the resulting executable code might have been the case in 1970; it certainly is not now. Optimizing compilers are good, and you have bigger worries than a nanosecond here or there. The idea that the += operator was developed "twenty years ago" is obviously false; the late Dennis Richie developed C from 1969 through 1973 at Bell Labs. –  Eric Lippert Feb 10 '12 at 1:19
show 2 more comments

22 Answers 22

up vote 305 down vote accepted

It's not a shorthand.

The += symbol appeared in the C language about 20 years ago, and - with the C idea of "smart assembler" correspond to a clearly different machine instruction: += maps to INC, while + maps to ADD.

With a clean idea that the first is operating on x, while the second is evaluating an expression and later place the result in a given place.

Enabling compiler optimization the correspondence can be swapped based on convenience, but there is still a conceptual difference.

x += 5 means

  • find the place identified by x
  • add 5 to it,

but x = x + 5 means:

  • evaluate x+5
    • find the place identified by x
    • copy x into an accumulator
    • add 5 to the accumulator
  • store the result in x
    • find the place identified by x
    • copy the accumulator to it.

Of course, optimization can

  • if "finding x" has no side effects, the two "finding" can be done once (and x become an address stored in a pointer register)
  • the two copy can be elided if the ADD is applied to &x instead to the accumulator

thus making the optimized code to coincide the x += 5 one.

But this can be done only if "finding x" has no side effects, otherwise

*(x()) = *(x()) + 5;

and

*(x()) += 5;

are semantically different, since x() side effects will be produced twice or once.

The equivalence between x = x + y and x += y is hence due to the particular case where += and = are applied to a direct l-value.


[EDIT: Following Brendan Comment]

Yes, in the x86 family, ++ maps INC, += maps ADD() and + maps ADD I'm not referring to any specific assembly language, but to an aspect of processors architectures:

Every CPU has an ALU (arithmetic-logical unit) that is -in its very essence- a combinatorial network whose inputs and output are "plugged" to the registers and / or memory depending on the opcode of the instruction

Binary operations are typically implemented as "modifier of an accumulator register with an input taken "somewhere", where somewhere can be - inside the instruction flow itself (typical for manifest contant: ADD A 5) - inside another registry (typical for expression computation with temporaries: e.g. ADD A B) - inside the memory, at an address given by a register (typical of data fetching e.g.: ADD A (H)) - H, in this case, work like a dereferencing pointer.

With this pseudocode, x+=5 is

ADD (X) 5

while x = x+5 is

MOVE A (X)
ADD A 5
MOVE (X) A

That is x+5 gives a temporary that is later assigned. x+=5 operates directly on x.

The actual implementation depends on the real instruction set of the processor: If there is no ADD (.) c the first code becomes the second. If there is and optimization are enabled the second code become the first.

share|improve this answer
48  
+1 for the only answer explaining that it used to map to different (and more efficient) machine code back in the olden days. –  Péter Török Feb 9 '12 at 8:47
5  
@KeithThompson That is true but one cannot deny that assembly had a huge influence over the design of the C language (and subsequently all C style languages) –  MattDavey Feb 9 '12 at 9:39
41  
Erm, "+=" doesn't map to "inc" (it maps to "add"), "++" maps to "inc". –  Brendan Feb 9 '12 at 12:46
10  
By "20 years ago", I think you mean "30 years ago". And BTW, COBOL had C beat by another 20 years with: ADD 5 TO X. –  JoelFan Feb 9 '12 at 16:29
9  
Great in theory; wrong in facts. The x86 ASM INC only adds 1, so it doesn't affect the "add and assign" operator discussed here (this would be a great answer for "++" and "--" though). –  Mark Brackett Feb 9 '12 at 18:45
show 16 more comments

For some insight to why these operators are in the 'C-style' languages to begin with, there's this excerpt from K&R 1st Edition (1978), 34 years ago:

Quite apart from conciseness, assignment operators have the advantage that they correspond better to the way people think. We say "add 2 to i" or "increment i by 2," not "take i, add 2, then put the result back in i." Thus i += 2. In addition, for a complicated expression like

yyval[yypv[p3+p4] + yypv[p1+p2]] += 2

the assignment operator makes the code easier to understand, since the reader doesn't have to check painstakingly that two long expressions are indeed the same, or wonder why they're not. And an assignment operator may even help the compiler to produce more efficient code.

I think it's clear from this passage that K&R believed that compound assignment operators helped with code readability.

It's been a long time since K&R wrote that, and a lot of the 'best practices' about how people should write code has changed or evolved since then. But this programmers.stackexchange question is the first time I can recall someone voicing a complaint about the readability of compound assignments, so I wonder if many programmers find them to be a problem? Then again, as I type this the question has 95 upvotes, so maybe people do find them jarring when reading code.

share|improve this answer
add comment

The other answers target the more common cases, but there is another reason: In some programming languages, it can be overloaded; e.g. Scala.


Small Scala lesson:

var j = 5 #creates a variable
j += 4    #compiles

val i = 5 #creates a constant
i += 4    #doesn’t compile

If a class only defines the + operator, x+=y is indeed a shortcut of x=x+y.

If a class overloads +=, however, they are not:

var a = ""
a += "this works. a now points to a new String"

val b = ""
b += "this doesn’t compile, as b cannot be reassigned"

val c = StringBuffer() #implements +=
c += "this works, as StringBuffer implements “+=(c: String)”"

edit: additionally operators + and += are two separate operators (and not only these: +a, ++a, a++, a+b a += b are different operators as well); in languages where operator overloading is available this might create interesting situations. Just as described above - if you'll overload + operator to perform the adding, bear in mind that += will have to be overloaded as well.

share|improve this answer
show 1 more comment

I didn't notice anyone mentioning that you eliminate duplication of a reference.

someLongWindedIdentifireName = someLongWindedIdentifireName + 1

has one more chance of typo than it's shorthand version, and the information density is increased without introducing any indirection, so in my book, complexity goes down.

share|improve this answer
add comment

It's not a only a good practice, it's better!

 int a = 5;
 a += 5;

The bytecode of this code is:

0:  iconst_5
1:  istore_1
2:  iinc    1, 5

Instead the exploded code of "+=" operator,

int a = 5;
a = a + 5;

is translated by:

0:  iconst_5
1:  istore_1
2:  iload_1
3:  iconst_5
4:  iadd
5:  istore_1

In conclusion, less (byte)code, more speed!

Less (source)code is more readable and it is high maintainable.

share|improve this answer
4  
That might have been true 35 years ago, before optimizing compilers. –  Todd Lehman Feb 9 '12 at 21:04
show 1 more comment

At least in Python, x += y and x = x + y can do completely different things.

For example, if we do

a = []
b = a

then a += [3] will result in a == b == [3], while a = a + [3] will result in a == [3] and b == []. That is, += modifies the object in-place (well, it might do, you can define the __iadd__ method to do pretty much anything you like), while = creates a new object and binds the variable to it.

This is very important when doing numerical work with NumPy, as you frequently end up with multiple references to different parts of an array, and it is important to make sure you don't inadvertently modify part of an array that there are other references to, or needlessly copy arrays (which can be very expensive).

share|improve this answer
show 2 more comments

Say it once and only once: in x = x + 1, I say 'x' twice.

But do not ever write, 'a = b +=1' or we will have to kill 10 kittens, 27 mice, a dog and a hamster.

Some people argue that you should never change the value of a variable, as it makes it easier to prove the code is correct.

share|improve this answer
add comment

It's actually faster way to add. Here are the methods of incrementing, ordered by fastest to slowest:

$i += 1;
++$i;
$i++;
$i = $i + 1;
share|improve this answer
3  
Editing the program and results into the answer would improve it no end. –  ChrisF Feb 9 '12 at 12:14
9  
Mentioning the language would help here. It looks like Perl to me. Remove the '$' sigils and any halfway decent C/C++/Java/whatever compiled language compiler is going to emit the same code for any of them. –  David Thornley Feb 9 '12 at 15:02
show 3 more comments

It's true that it's shorter and easier, and it's true that it was probably inspired by the underlying assembly language, but the reason it's best practice is that it prevents a whole class of errors, and it makes it easier to review the code and be sure what it does.

With

RidiculouslyComplexName += 1;

Since there's only one variable name involved, you're sure what the statement does.

With RidiculouslyComplexName = RidiculosulyComplexName + 1;

There's always doubt that the two sides are exactly the same. Did you see the bug? It gets even worse when subscripts and qualifiers are present.

share|improve this answer
show 1 more comment

It is a nice idiom. Whether it is faster or not depends on the language. In C, it is faster because it translates to an instruction to increase the variable by the right hand side. Modern languages, including Python, Ruby, C, C++ and Java all support the op= syntax. It's compact, and you get used to it quickly. Since you will see it a whole lot in OPC (other peoples' code), you may as well get used to it and use it. Here is what happens in a couple of other languages.

In Python, typing x += 5 still causes the creation of the integer object 1 (although it may be drawn from a pool) and the orphaning of the integer object containing 5.

In Java, it causes a tacit cast to occur. Try typing

int x = 4;
x = x + 5.2  //this causes a compiler error
x += 5.2     // this is not an error; an implicit cast is done.
share|improve this answer
show 1 more comment

Besides the obvious merits which other people described very well, when you have very long names it is more compact.

  MyVeryVeryVeryVeryVeryLongName += 1;

or

  MyVeryVeryVeryVeryVeryLongName =  MyVeryVeryVeryVeryVeryLongName + 1;
share|improve this answer
add comment

It is shorter.

I don't mean by typed letters (shorter names are not good style), but by count of instructions. The reason for this to be better is the number of possible failures.

If you change x in x = x + 5; you must make sure, that you change both x, while you have to change only one in x += 5;. Though it doesn't look much in this example, it's good practice and with it good style. (If you have your doubts think of

MaxLabelsPerSheet = MaxLablesPerSheet + 5;

instead).

share|improve this answer
add comment

I think that, more important than which one you use (x = x + 5 or x += 5) is to pick one and stick with it. Don't mix it up. It can be a little confusing (and annoying) to see both variants multiple times in the same method/function.

share|improve this answer
5  
I'd find it confusing to see any occurance of x = x + 5 at all, regardless of whether there are also +=s about. –  leftaroundabout Feb 9 '12 at 20:11
add comment

Consider this

(some_object[index])->some_other_object[more] += 5

D0 you really want to write

(some_object[index])->some_other_object[more] = (some_object[index])->some_other_object[more] + 5
share|improve this answer
add comment

Operators such as += are very useful when you're using a variable as an accumulator, i.e. a running total:

x += 2;
x += 5;
x -= 3;

Is a lot easier to read than:

x = x + 2;
x = x + 5;
x = x - 3;

In the first case, conceptually, you're modifying the value in x. In the second case, you're computing a new value and assigning it to x each time. And while you'd probably never write code that's quite that simple, the idea remains the same... the focus is on what you're doing to an existing value instead of creating some new value.

share|improve this answer
add comment

To put @Pubby's point a little clearer, consider someObj.foo.bar.func(x, y, z).baz += 5

Without the += operator, there are two ways to go:

  1. someObj.foo.bar.func(x, y, z).baz = someObj.foo.bar.func(x, y, z).baz + 5. This is not only awfully redundant and long, it's also slower. Therefore one would have to
  2. Use a temporary variable: tmp := someObj.foo.bar.func(x, y, z); tmp.baz = tmp.bar + 5. This is ok, but it's a lot of noise for a simple thing. This is actually really close to what happens at runtime, but it's tedious to write and just using += will shift the work to the compiler/interpreter.

The advantage of += and other such operators is undeniable, while getting used to them is only a matter of time.

share|improve this answer
3  
@Dorus: The expression I chose is just an arbitrary representative for "complex expression". Feel free to replace it by something in your head, that you wont nitpick about ;) –  back2dos Feb 9 '12 at 12:50
4  
+1: This is the principle reason for this optimization -- it's always correct, no matter how complex the left-hand-side expression is. –  S.Lott Feb 9 '12 at 13:24
6  
Putting a typo in there is a nice illustration of what can happen. –  David Thornley Feb 9 '12 at 14:59
show 1 more comment

Besides readability, they actually do different things:+= doesn't have to evaluate its left operand twice.

For instance, expr = expr + 5 would evalaute expr twice (assuming expr is impure).

share|improve this answer
6  
@vsz Not if expr has side effects. –  Pubby Feb 9 '12 at 7:36
4  
@vsz: In C, if expr has side effects, then expr = expr + 5 must invoke those side effects twice. –  Keith Thompson Feb 9 '12 at 9:18
2  
Better be careful about those "side effects" statements. Reads and writes to volatile are side effects, and x=x+5 and x+=5 have the same side effects when x is volatile –  MSalters Feb 9 '12 at 12:13
show 2 more comments

While the += notation is idiomatic and shorter, these are not the reasons why it is easier to read. The most important part of reading code is mapping syntax to meaning, and so the closer the syntax matches the programmer's thought processes, the more readable it will be (this is also the reason why boilerplate code is bad: it is not part of the thought process, but still necessary to make the code function). In this case, the thought is "increment variable x by 5", not "let x be the value of x plus 5".

There are other cases where a shorter notation is bad for readability, for example when you use a ternary operator where an if statement would be more appropriate.

share|improve this answer
add comment

It's concise.

It's much shorter to type. It involves less operators. It has less surface area, less opportunity for confusion.

It uses a more specific operator.

This is a contrived example and I'm not sure if actual compilers implement this. x += y actually uses one argument and one operator and modifies x in place. x = x + y could have an intermediate representation of x = z where z is x + y. The latter uses two operators, addition and assignment, and a temporary variable. The single operator makes it super clear that the value side can't be anything other than y and doesn't need to be interpreted. And there could theoretically be some fancy CPU that has a plus-equals operator that runs faster than a plus operator and an assignment operator in series.

share|improve this answer
1  
Theoretically schmeoretically. The ADD instructions on many CPUs have variants that operate directly on registers or memory using other registers, memory or constants as the second addend. Not all combinations are available (e.g. add memory to memory), but there are enough to be useful. At any rate, any compiler with a decent optimizer will know to generate the same code for x = x + y as it would for x += y. –  Blrfl Feb 9 '12 at 11:43
show 1 more comment

It is called an idiom. Programming idioms are useful because they are a consistent way of writing a particular programming construct.

Whenever someone writes x += y you know that x is being incremented by y and not some more complex operation (as a best practice, typically I wouldn't mix more complicated operations and these syntax shorthands). This makes the most sense when incrementing by 1.

share|improve this answer
9  
x++ and ++x are slightly different to x+=1 and to each other. –  Gary Willoughby Feb 9 '12 at 13:44
1  
@Donal Fellows: The precedence is different, so ++x + 3 isn't the same as x += 1 + 3. Parenthesize the x += 1 and it's identical. As statements by themselves, they're identical. –  David Thornley Feb 10 '12 at 21:21
show 3 more comments

On the other hand it is more readable because it's less to read and removes any kind ambiguity on what variables it is adding on (ie.ab = ad + 1;)

share|improve this answer
add comment

Depending on how you think about it, it's actually easier to understand because it's more straightforward. Take, for example:

x = x + 5 invokes the mental processing of "take x, add five to it, and then assign that new value back to x"

x += 5 can be thought of as "increase x by 5"

So, it's not just shorthand, it actually describes the functionality much more directly. When reading through gobs of code, it's much easier to grasp.

share|improve this answer
18  
+1, I totally agree. I got into programming as a kid, when my mind was easily malleable, and x = x + 5 still troubled me. When I got into maths at a later age, it bothered me even more. Using x += 5 is significantly more descriptive and makes much more sense as an expression. –  Polynomial Feb 9 '12 at 12:14
24  
There's also the case where the variable has a long name: reallyreallyreallylongvariablename = reallyreallyreallylongvariablename + 1 ... oh noes!!! a typo –  Matt Fenwick Feb 9 '12 at 13:44
5  
@Matt Fenwick: It doesn't have to be a long variable name; it could be an expression of some sort. Those are likely to be even harder to verify, and the reader has to spend a lot of attention to make sure they're the same. –  David Thornley Feb 9 '12 at 14:57
8  
X=X+5 is sort of a hack when your goal is to increment x by 5. –  JeffO Feb 10 '12 at 1:08
show 2 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.