How Not To Swap Two Numbers

At a recent interview a junior developer asked me to describe a way of swapping two numbers without using a temporary. I find what the programmer had in mind particularly scary, but perhaps precisely because of this it's a great vehicle to investigate some important concepts at a technical interview.

It's also getting close to Halloween so in the spirit of scary things …

How to Swap 2 Numbers Using a Temporary

This is how numbers are swapped in software.

numeric a = 4;
numeric b = 6;

/* now swap */
numeric temporary = a;
a = b;
b = temporary;

/* swapped, now a==6 and b==4 */

Q: Is there another way to do this?
An experienced developer will know that this is pretty much it. Whether you are using a high level language or swapping with a single assembly instruction (XCHG etc.), it's the same process conceptually, i.e. temporary (or transitory) space is employed to move the value from one location to the other without loss of representation. A qualified candidate should know this without being confused by the superficial differences between programming languages and without being tempted to stray into the land of the truly bizarre.

How to Swap 2 Numbers Without using a Temporary

// begin: NEVER DO THIS
numeric a = 4;
numeric b = 6;

/* now funky swap */
a = a + b;        // a is now 10, maybe
b = a - b;        // b is now 4, maybe
a = a - b;          // a is now 6, maybe

/* swapped, now a==6 and b==4 ... (maybe) */
// end: NEVER DO THIS

Q: Will this work?
You've established a discussion point here regardless of the answer. However, acceptance of this solution as a bright and novel innovation is a red flag.

Q: What are the issues?
In short, overflow and loss of precision. The former with fixed point representation, the later with floating point.
Exactly what could go wrong here, what might work in practice and what are the portability issues are some
of the many interesting discussions facilitated by this example.

Q: Does this program employ temporary variables?
Ironically, this snippet actually uses implied temporaries (see discussion below), perhaps as much as 3x the original depending on programming language and the sequence of instructions used.

Performance

The temporary-less suggested solution has significantly more instructions that the simpler one with an explicit temporarily. A smart compiler may be able to optimize this somewhat, but again the irony is that this optimization process may result in the introduction of the temporaries.

Scary

The disturbing issue here is the suggested introduction of an optimization that would seem harmless and would likely pass development and testing without further issue only to fail at the worst possible time. Once in the field however the bug may encounter the rare conditions would cause the program to deviate from planned operation. At that point correct operation of the program may have become of critical importance. Resolution of the bug would likely be a nightmare; monitoring and debugging infrastructure may no longer exist, key people unavailable, reproduction difficult.

It's important to remind that these days many critical system rely on software. It's not just about the inconvenience of a computer reboot. Weapons, safety systems at nuclear power plants, heart pacemakers, aircraft control systems all use software.

Philosophy

This question touches on a range of programming philosophy issues in addition to the important nuts and bolts. The following points are well-oft repeated, but still worth listing again.

Never Try to Be Clever

Never do this.

Ever.

If inspiration hits it's least likely to occur when you are trying to be clever.

Don't Be Clever

Being clever is also ill-advised.

Experienced programmers write code by repeating expressions, sequences and patterns that they once established as bullet-proof and repeated ever since. All experienced developers use the same basic toolbox, albeit with differing syntax and other superficial artefacts. Just like a toolbox. No points for inventing the rubber chisel.

Being standard and predicable means developers (and that includes you) will read your code faster, compilers will create more optimal programs, testers will test better and you'll have less bugs.