Duplicate the swap function

Attributes[swap] = HoldAll;

swap[x_, y_] := {x, y} = {y, x};

x = 1;
y = 2;

swap[x, y];

{x, y}
{2, 1}

There are two characteristics of this code worth noting. The first is the HoldAll Attribute:

  • How do I treat elements in a list as variables inside a module?
  • When should I, and when should I not, set the HoldAll attribute on a function I define?
  • Pass function or formula as function parameter
  • How to modify function argument?

The second is the evaluation of {x, y} = {y, x} itself, which is related. Let us consider how else we might implement this. Essentially we need to store the present values of x and y before reassigning these Symbols to the opposite value. That might be done verbosely like this:

x1 = x;
y1 = y;
x = y1;
y = x1;

This requires that two additional Symbols be introduced which is less clean than ideal. Instead we can store the original values within the evaluation sequence itself. First understand that Set (short form =) has the HoldFirst attribute. This means that in the expression {x, y} = {y, x} (long form Set[{x, y}, {y, x}]) the second argument will be evaluated before Set does anything, but the first argument will be held in an unevaluated form. Indeed we find this in the output of TracePrint:

x = 1;  y = 2;

TracePrint[{x, y} = {y, x}];

  (* other print lines omitted*)

{x, y} = {2, 1}

Thanks to the fact that Set operates on lists this then performs the reassignment that we want. If it did not we could still perform this action without using intermediate (temporary) variables like x1 and y1 by using the same kind of evaluation control.

(x = #2; y = #1) &[x, y]

Here a Function is used which (by default) evaluates its arguments but holds the body of the function (x = #2; y = #1) unevaluated until its Slots are filled.


Just a reminder for advanced users, to show the complexity of the problem :

enter image description here

enter image description here

keywords : David Wagner power programming swap byname