2

I am trying to debug some script and need to Print[] out some results, sometimes before, and sometimes after, certain executions.

These 3 trials exemplify my question, and the last one is where my problem is -- How do I print out previously calculated results with in parenthesis? (e.g. "previous result is: ..." should be visible)

In[12]:= ClearAll[f, x];
f[x_] := f[x] = Which[
   x == 0, 1,
   x == 1, (Print["at x=1 "]; 1),
   x >= 1, (x*f[x - 1]; Print["main one..."])
   ]

In[14]:= f[2]

During evaluation of In[14]:= at x=1 

During evaluation of In[14]:= main one...

In[15]:= ClearAll[g, x];
g[x_] := g[x] = Which[
   x == 0, 1,
   x == 1, (Print["at x=1 "]; 1),
   x >= 1, (x*g[x - 1]; Print["main one..."])
   ]

In[17]:= g[2]

During evaluation of In[17]:= at x=1 

During evaluation of In[17]:= main one...

In[22]:= ClearAll[h, x];
h[x_] := h[x] = Which[
   x == 0, 1,
   x == 1, (Print["at x=1 "]; 1),
   x >= 1, (Return[x*h[x - 1]]; Print["previous result is: ..."])
   ]

In[24]:= h[3]

During evaluation of In[24]:= at x=1 

Out[24]= 6

This http://reference.wolfram.com/language/ref/CompoundExpression.html?view=all wasn't too helpful, except I think it returns only the last expression in a pair of (). These examples only show the Print[] operation before the desired return value... Create recursive sequence of functions with memoization

UPDATE

Maybe I should clarify.

I want this:

ClearAll[h, x];
h[x_] := h[x] = Which[
   x == 0, 1,
   x == 1, (Print["at x=1 "]; 1),
   x >= 1, (x*h[x - 1]; Print["leaving"])
   ]

h[4]

at x=1 

leaving

leaving

leaving

but also the result to be used in a further, continuing calculation. This way I know it has successfully left this case of Which[].

nate
  • 445
  • 2
  • 7

2 Answers2

2

To perform some actions after computing the result but before returning it, you can use With to store the result temporarily:

ClearAll[h, x];
h[x_] := h[x] = Which[
   x == 0, 1,
   x == 1, (Print["at x=1 "]; 1),
   x >= 1, With[{res=x*h[x - 1]}, Print["leaving"]; res]
   ]

h[4]
(* at x=1 *)
(* leaving *)
(* leaving *)
(* leaving *)
(* 24 *)

For this particular example, you can further use the following, more Mathematica-like approach:

ClearAll[h, x];
h[0] = 1;
h[1] := (Print["at x=1"]; 1)
h[x_] := h[x] = With[{res=x*h[x - 1]}, Print["leaving"]; res]

An alternative to With and @CarlWoll's answer might also be to (ab)use EchoFunction:

ClearAll[h, x];
h[0] = 1;
h[1] := (Print["at x=1"]; 1)
h[x_] := h[x] = EchoFunction["leaving" &][x*h[x - 1]]
Lukas Lang
  • 33,963
  • 1
  • 51
  • 97
  • Both great answers! I guess for compactness though I'll try to avoid clutter with a helper function and go with With[]. Now to try and utilize it in https://mathematica.stackexchange.com/questions/180143/recursion-stuck-for-a-memoizing-function – nate Aug 21 '18 at 16:00
1

You could define a helper function:

myprint[control_, x_]:=(Print[StringForm[control, x]]; x)

Then:

ClearAll[h, x];
h[x_] := h[x] = Which[
    x == 0, 1,
    x == 1, myprint["at x=`1`", x],
    x >= 1, myprint["previous result is: `1`", x*h[x - 1]]
]

h[4]

at x=1

previous result is: 2

previous result is: 6

previous result is: 24

24

Carl Woll
  • 130,679
  • 6
  • 243
  • 355
  • 1
    An alternative to a custom helper function might be to use EchoFunction[StringTemplate["previous result is: `1`"]][x * h[x - 1]] – Lukas Lang Aug 20 '18 at 14:52