According to the manual, "A variable defined with SetDelayed is evaluated every time it is used". The code below suggests otherwise.
x : t[a_] /; ! TrueQ[c] := Block[{c = True}, w[x]];
w /: Times[a_w, b__] /; ! TrueQ[c] :=
Block[{c = True},
w[Times @@ Replace[Prepend[{b}, a], x_w :> x[[1]], {1}]]];
e := a t[1]
output = {a t[1], e, e, a t[1]}
The output is
{w[a t[1]], w[a t[1]], a t[1], w[a t[1]]}
The first element is the result of evaluating the same expression as the right hand side of the definition of e
. That is a t[1] -> w[a t[1]]
as expected.
The second element is the first evaluation of e
. That is e -> w[a t[1]]
as expected. The first and second elements are equal to each other because they both evaluate a t[1]
.
The third element is the second evaluation of e
. However, this time e -> a t[1]
. In my understanding of the manual, this entry should be w[a t[1]]
not a t[1]
.
The fourth element is there to check if there is an issue with successive evaluations of a t[1]
. It evaluates to w[a t[1]]
as expected.
Question: What is part of the evaluation process that causes the unexpected result?
e := a t[1] RandomReal[1]
one can see thate
is evaluated the second time. It's the upvalue forw
that seems to be skipped. $\endgroup$Update
resets the status. For example, ifUpdate
is called between the 4th and 5th evaluation ofe
, then the 4th evaluation behaves as the second (now
), the 5th behaves as the first (hasw
), the 6th and subsequent behave as the second (now
again). The question is why? $\endgroup$