I think there are some issues with how Unevaluated is parsed by some of
Mathematica functions. Consider
In[1]:=
Module[
{L = {}},
L = Append[L, Unevaluated @ Sequence[a,b]]
]
Module[
{L = {}},
AppendTo[L, Unevaluated @ Sequence[a,b]]
]
Out[1]=
{a,b}
Append::argrx: Append called with 3 arguments; 2 arguments are expected.
Out[2]=
Append[{},a,b]
which means that what the description of AppendTo in the Reference says
("AppendTo[s, elem] is equivalent to s = Append[s, elem]") is not quite true.
What seems to happen here is that firstly Unevaluated @ Sequence[a,b] is
evaluated as the second argument of AppendTo (and Unevaluated gets stripped) and
then AppendTo is internally rewritten as L = Append[L, Sequence[a,b]] (and
Sequence[a,b] is evaluated and spliced in). So to get the desired result we
should use
In[2]:=
Module[
{L = {}},
AppendTo[L, Unevaluated @ Unevaluated @ Sequence[a,b]]
]
Out[2]=
{a,b}
but how should one figure it out, except by educated guessing? Or consider
In[1]:=
Unevaluated @ D[y,x] /. {y -> x}
Unevaluated @ D[y,x] /. {{y -> x}}
Out[1]=
1
Out[2]=
{0}
Here we can see that {ReplaceAll[expr,{rule}]} is not equivalent to
ReplaceAll[expr,{{rule}}], contrary to what notes for Replace say. In the second
case two Unevaluated wrappers are needed as well -- three for three levels of
rule nesting and so on. But once again, a user can see only one function,
ReplaceAll, acting on Unevaluated, why should he bother about internal
transformations?
Another example:
In[1]:=
Module[{x}, x = Unevaluated[1 + 1]]
Module[{x = Unevaluated[1 + 1]}, x]
Out[1]=
2
Out[2]=
Unevaluated[1 + 1]
This is the same problem in disguise: in one case Unevaluated is processed as
the argument of Set, in the other Set is not called. Another -- unrelated --
issue is
In[1]:=
Unevaluated[1 + 1] == 2
Out[1]=
Unevaluated[1 + 1] == 2
The fact that Unevaluated doesn't disappear in this case is well known, but it
seems to contradict what section "A.4.1 The Standard Evaluation Sequence" of the
Book says.
Maxim Rytin
m.r at prontomail.com