4
$\begingroup$

I enjoy using "%" to capture the previous output as it allows me to split big tasks into chunks without having to introduce lots of intermediate variable names. Consider an overly simple example:

x = 2;
x + 4;
%^2;
y = % - 3;
{x, y}
(*{2, 33}*)

How can I accomplish a similar thing inside Module. I naively tried

f[x_] := Module[{y},
  x + 4;
  %^2;
  y = % - 3;
  {x, y}
  ]
f[2]
(*{2, -3 + Null}*)

but that didn't work.

$\endgroup$
5
  • $\begingroup$ I don't think % can work inside a Module, but if you don't want unnecessary variables, can't you do something likey = x + 4; y = y^2; y = y - 3? $\endgroup$ Commented Jun 18, 2016 at 15:32
  • 1
    $\begingroup$ f[x_] := Module[{y}, x + 4 // #^2 & // (y = # - 3) &; {x, y}]? $\endgroup$
    – Karsten7
    Commented Jun 18, 2016 at 15:32
  • 1
    $\begingroup$ @MariusLadegårdMeyer, I could do, put it upsets my sensibilities using a variable for intermediate steps when the results of the intermediate steps are not what that variable is supposed to represent. Perhaps I'm being a tad particular though! $\endgroup$
    – Tom
    Commented Jun 18, 2016 at 15:35
  • $\begingroup$ @Karsten7. hmm yeah maybe that could do it. Although in reality each line is quite long so I need to have an individual line for each step, and splitting up your suggestion into individual lines looks a bit messy from the way Mathematica formats it. $\endgroup$
    – Tom
    Commented Jun 18, 2016 at 15:40
  • $\begingroup$ Starting each line with // might look better (but still strange). It's also more typing and one should not forget the extra () in things like (y = # - 3) &. $\endgroup$
    – Karsten7
    Commented Jun 18, 2016 at 15:45

1 Answer 1

4
$\begingroup$

This is not a problem peculiar to Module; % won't work in the way you expect in any function definition because it always refers to the last top-level output. Consider, the much simpler

g[x_] := (x^2; % + 1)

42

42

g[5]

43

g[5]

44

You see that g ignores the previous evaluation of x^2 and returns the last top-level output increased by 1.

My recommendation for those times when you want to compute a complicated expression in steps is to use a single local variable repeatedly. Thus, I would rewrite f as

f[x_] :=
  Module[{y},
    y = x + 4;
    y = y^2;
    y = y - 3;
    {x, y}]

To check that this gives same result as writing the computation as a single expression, I write

h[x_] := {x, (x + 4)^2 - 3}

Then

f[x] == h[x]

gives

True

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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