Because defining the function:
swap[x_, y_] := Module[{}, t = x; x = y; y = t; Return[]]
and writing:
swap[x, y]
{x, y}
I get:
{y, y}
and not {y, x}
as I would like?
Thank you!
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:
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 Slot
s are filled.
Just a reminder for advanced users, to show the complexity of the problem :
keywords : David Wagner power programming swap byname
swap
meant to swap the values stored inx
andy
, or is it meant to symbolically swap the two expressions? $\endgroup$Module
here? What is the point ofReturn
? $\endgroup$Module
, you may want to read this, as toReturn
, you may want to read this. $\endgroup$