I had gotten used to thinking of the placement of a condition in a rule definition as logically immaterial. In my specific example, namely
ClearAll[f,g,h];
SetAttributes[f,HoldAllComplete];
f[x_ /; Head@Unevaluated@x === Symbol] := x;
SetAttributes[g,HoldAllComplete];
g[x_] := x /; Head@Unevaluated@x === Symbol;
SetAttributes[h,HoldAllComplete];
h[x_] /; Head@Unevaluated@x === Symbol := x;
all three produce the same results when applied to the same symbol
In[13]:= f[foo] === g[foo] === h[foo] === foo
(* Out[13]= True *)
But now I try to get fancy and write the following
ClearAll[f, g, h, foo];
SetAttributes[f,HoldAllComplete];
f[x_ /; Head@Unevaluated@x === Symbol] := Unevaluated@x;
SetAttributes[g,HoldAllComplete]
g[x_] := Unevaluated@x /; Head@Unevaluated@x === Symbol;
SetAttributes[h,HoldAllComplete]
h[x_] /; Head@Unevaluated@x === Symbol := Unevaluated@x;
In[20]:= {f[foo], g[foo], h[foo]}
and the results are very different
(* Out[20]= {foo, Unevaluated[foo], foo} *)
I try to figure it out with traceView2; I can see the differences
but I get quickly lost in the documents trying to understand what, why, and how. Seems even this example is not so simple and probes dark (at least to me) corners of the evaluator. I'd be grateful for advice, explanations, ideas.
Unevaluated
itself. Working on an answer now. $\endgroup$