Another difference between Set and SetDelayed. Evaluation shortcut?
I thought to give a bit more insight into why Update
is needed, as pointed out in the other answers. Its documentation says Update
may be needed when a change in 1 symbol changes another via a condition test.
In Jacob's example, setting count = 0
changes the condition test outcome, and thus a
or b
on the LHS. Consequently, a
or b
on the RHS is supposed to change. However, RHS a
equals the old LHS a
, which was undefined because count>=20
, and needs Update
to be changed. RHS b
behaves the same, but was not evaluated in SetDelayed
because Evaluate
occurs before SetDelayed
, so count
is unchanged, and RHS b
evaluates to LHS b
with count<20
. If we now reset count=0
, evaluating b
will return {b}
.
To illustrate, I modify the example to separate LHS and RHS. MMA is clever enough to automatically update LHS declared as a variable, so I have to make a function:
count=0;
ClearAll[LHS,RHS];
LHS[]/;(count++<20)={RHS};
RHS=Unevaluated@LHS[];
count=0;
RHS (* Equals LHS[] with count >= 20 *)
(* Tell Wolfram Language about changes affecting RHS which depends on LHS *)
Update@Unevaluated@LHS;
RHS
LHS[]
{{{{{{{{{{{{{{{{{{{{LHS[]}}}}}}}}}}}}}}}}}}}}
Extended comment. Also: If Rojo wants to post an answer, I can delete this
It seems Rojo was right, guessing that it had to do with Update
.
count = 0;
ClearAll@a2
a2 /; (Update[Unevaluated@a2]; count++ < 20) = {a2}
a2 // OwnValues
count = 0;
a2
Output
{{{{{{{{{{{{{{{{{{{{{a2}}}}}}}}}}}}}}}}}}}}}
{HoldPattern[a2 /; (Update[Unevaluated[a2]]; count++ < 20)] :> {a2}}
{{{{{{{{{{{{{{{{{{{{a2}}}}}}}}}}}}}}}}}}}}
I think user obsolesced rightly pointed out why there is an additional pair of brackets in the first output. This is because there is already a pair of brackets on the right hand side of Set
and {a2}
is evaluated rather than a2
.
Also an extended comment; using Update[]
makes the first recursion behave as expected:
count = 0;
ClearAll@a
a /; (count++ < 20) = {a};
count = 0;
Update[]
a
{{{{{{{{{{{{{{{{{{{{a}}}}}}}}}}}}}}}}}}}}
Apparently the LHS condition is affected by the use of Set
versus SetDelayed
. Certainly worth more exploration, but for me that will have to wait.