Extended comment
First of all, I think there is no easy answer to this question.
Let me collect my examples in an answer, in order to provide some structure in them as well as not to flood the comments. Throughout the answer, the lines of text describing the code refer to the code below it.
You will find that the examples which reach $IterationLimit
are much harder to understand. If there is nothing mysterious about x:={x}
creating infinitely much work for the kernel, then there is also nothing mysterious about x:=Identity[x]
causing infinitely much work.
Clear[f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, x, x2, x3, x4, x5]
The following reaches $RecursionLimit
x2:=Identity@x2;x2
No infiniteness
x=x;x
y //. y :> y
Infinite iteration
x3:=Identity[Unevaluated[x3]]; x3
No infiniteness
y//.HoldPattern[y]:>Identity[Unevaluated[y]]
a[y] //. HoldPattern[y] :> Identity[Unevaluated[y]]
Infinite iterations
Hold[y] //. HoldPattern[y] :> Identity[Unevaluated[y]]
SetAttributes[b, HoldFirst]; SetAttributes[c,HoldRest]
b[y] //. HoldPattern[y] :> Identity[Unevaluated[y]]
b[y, 1] //. HoldPattern[y] :> Identity[Unevaluated[y]]
c[1, y] //. HoldPattern[y] :> Identity[Unevaluated[y]]
No infiniteness
b[1, y] //. HoldPattern[y] :> Identity[Unevaluated[y]]
c[y, 1] //. HoldPattern[y] :> Identity[Unevaluated[y]]
No infiniteness
p : f1[x_] := p; f1[1]
p : f2[x_] /; True := p; f2[1]
p : f3[x_] := p /; True; f3[1]
Infinite iterations
p : f4[x_] := Identity@Unevaluated@p; f4[1]
f5[g_] := g[g]; f5[f5]
f6[x_] := f6[x]; f6[1]
(p : f7)[x_] := p[x]; f7[1]
No infiniteness
f8[_] := f8[1]; f8[1]
f9[] := f9[]; f9[]
f10[___] := f10[]; f10[]
Infinite iteration
Combining the previous definitions, we do get an infinite iteration.
f11[] := f11[];
f11[___] := f11[];
f11[]
Set vs SetDelayed
II
f[x_] = f[x]
Shortcut in action
We can do
p : f12[_] /; (x5 = True) := p
f12[x5]
which outputs
f17[x5]
and does set x5. So we see that x5 that after the replacement the expression is not properly evaluated.
Related, but not understandable: Unexpected behaviour of Unevaluated
x = x
is applied only once (no change);x := Identity[x]
leads to infinite recursion:Identity[Identity[…]]
because the argumentx
is evaluated beforeIdentity[x]
and becomesIdentity[x]
, in whichx
is evaluate beforeIdentity[x]
, ad infinitum. (In other words, Jacob is basically right.) $\endgroup$f[x_] := f[x]
has nothing to do withGlobal`x
, so let's usey
inf[y]
. I think difference is in how pattern replacements are handled. Whenf[y]
is evaluated, M evaluates the headf
first, finds the downvalue, applies it. Now, to apply it, M needs to evaluate the rhs,f
of the patternx
. After it does the substitution, the result has not been evaluated yet. So even though the result is againf[y]
,f[y]
has to be evaluated once more. Clearly you want this to happen for normal functions. Here you get infinite recursion. $\endgroup$ReplaceRepeated
examines the result of a replacement after evaluation is complete and continues until a fixed point is reached. After the first replacement, the expression is the same as the starting expression, so it stops. $\endgroup$