Recently someone posted the following question and bit of code to the Advanced Placement Computer Science teacher mailing list:
Assuming that all values are ints that have been properly initialized, which two of the following three lines of code are equivalent?
result1 -= result1 + x;
result2 = result2 - result2 + x;
result3 = result3 - (result3 + x);
This is a simple (well reasonably simple) question of precedence. The tricky part for most students is the first statement which includes –= . Tricky because a) it is easy to miss (I did on first reading) and b) people often either forget where that fits in the order of precedence or think that it doesn’t matter. OK probably solid professionals don’t mess this up but for beginners it is a landmine.
Choices B and C are pretty straight forward.In the first case subtracting result2 from itself leaves zero which added to x results in x. In the second case adding x to results3 and then subtracting the result from result3 leaves you with -x. Assuming you remember that these results don’t change the value of result2 until all the operations are finished. Choice C wisely uses parenthesis to make the desired order of operations crystal clear. Without the parenthesizes the computer will move from left to right doing the subtraction first. Yet another good example of why you want to use parenthesis. Which brings us back to choice A.
The –= has a lower precedence than the +. Remember that? Ok then realize that result1 + x does not change the value of result1 immediately. Rather it is held and then subtracted from result1 (its original value) before being reset to the result of this final operation. So choice A and C return the same result. Great!
The problem in my mind is that choice A is just too darn clever. Nothing of value is saved by not doing tings the way choice C is done. No operations are removed. Not registers are being saved. No extra value at all really. But it does add to the possible confusion and make understanding the program harder. The positives would have to really outweigh the negatives to make choice A a good implementation choice. Showing everyone how clever you are is not a positive BTW.
Your statement about B is wrong: if you do the subtraction first you get x; if you do the addition first you get -x. If you had result2 = x + result2 - result2 it really wouldn't matter which way round you did it.
Stu, you're right. I misspoke. The computer will move from left to right though so it does the subtraction first. I will edit the post.
I actually found (A) to be the easiest to read. This is partially an artifact of the examples given, since I kept trying to figure out why anyone would write "result2 - result2 + x" instead of simply "x". This applies to all 3 samples, but for me applied to (A) the least.
In general, the += notation is useful because it clearly shows that we're modifying a variable, instead of completely resetting it. Writing 'result += 3' clearly indicates an increase by 3, while 'result = result + 3' takes some thought to parse.
The examples are obviously contrived to illistrate a point. In fact this sort of contrivance is one thing that students of mine complained about over the years. We have too many examples of how not to do things in order to bemonstrate conceptes easily. That's just the way it has to be sometimes.
My take is that every programming language has its own specialized idioms, and before we teach one to beginning programmers we should ask whether it reflects a useful, general concept that would be cumbersome to show in a different way. I'm not convinced that -= falls into that category, in part because most other programming languages don't have it.
My college Programming Languages teacher referred to these elements as 'syntactic sugar' in that they didn't really add anything of value but in some cases sweeten the language for humans to read. But as with all things sugary, it is easy to abuse.