When you do
y = z^2/2;
fz[z_] := y;
fz[3]
the delayed evaluation f[z_]:=y
means that the right-hand side is memorized verbatim. You can check with ?fz
When you then call f[3]
, the replacement z->3
is done in the frozen y
, resulting in no replacement at all, since the verbatim y
does not contain z
.
After this useless replacement y/.z->3
is done, the result is unfrozen, and the outside rule y=z^2/2
gets finally applied.