9
$\begingroup$

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!

$\endgroup$
  • 2
    $\begingroup$ is swap meant to swap the values stored in x and y, or is it meant to symbolically swap the two expressions? $\endgroup$ – march Feb 7 '17 at 21:03
  • 2
    $\begingroup$ What is the point of Module here? What is the point of Return? $\endgroup$ – Marius Ladegård Meyer Feb 7 '17 at 21:06
  • $\begingroup$ As to Module, you may want to read this, as to Return, you may want to read this. $\endgroup$ – xzczd Feb 10 '17 at 11:51
13
$\begingroup$
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 Slots are filled.

$\endgroup$
  • 4
    $\begingroup$ @Manu You are welcome, and I am glad I can help. This really is not a stupid question as it requires some specific knowledge and understanding regarding evaluation semantics in Mathematica. It's actually a very nice minimal example of a couple of different properties. I suspect the question will end up being of use to other newish users. $\endgroup$ – Mr.Wizard Feb 7 '17 at 21:57
4
$\begingroup$

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

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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