15
$\begingroup$

Exploring another problem and this example of @halirutan, I came across an evaluation behavior I don't understand.

When g[] below is evaluated the first time, ig[] is evaluated and a message printed; on subsequent calls to g[], ig[] is not evaluated. This can be verified with Trace.

ClearAll[g, ig];
g::msg = "Message";
ig[] := Module[{}, Null /; (Message[g::msg]; False)];
g[] := Module[{res = ig[]}, res /; FreeQ[res, ig]];

It is as if Mathematica decided that ig[] is constant and assumes it does not need to be called further. However, each time ig[] is executed in the front end directly, it is evaluated, a message is printed, and it returns ig[].

With the modification below, in which ih[] is not constant, the first four times h[] is evaluated the function ih[] is evaluated. In subsequent evaluations of h[], ih[] is not evaluated again.

ClearAll[h, ih];
h::msg = "Message";
n = 2^4;
ih[] := Module[{}, n /; (n /= 2; Message[h::msg]; EvenQ[n])];
h[] := Module[{res = ih[]}, res /; FreeQ[res, ih]];

That is, once n becomes odd and EvenQ[n] tests False, the evaluation of h[] seems to change so that ih[] is no longer called from within h[].

Is this right, or am I missing something? Is this how it should be?

$\endgroup$
18
$\begingroup$

You need to use Update, e.g. Update[ig] or Update[ih], to tell Mathematica that the condition has changed and it should reevaluate ig or ih.

Also, see (1765) and (79486).

$\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.