# Unevaluated @ {args} versus Unevaluated /@ {args}

Working my way through Robby Villegas's lovely notes on withholding evaluation, I almost got Polish Notation on my first try. Here is my final solution, which seems to work well enough:

ClearAll[lispify];
SetAttributes[lispify, HoldAll];
lispify[h_[args___]] :=
Prepend[
lispify /@ Unevaluated @ {args},
lispify[h]];
lispify[s_ /; AtomQ[s]] := s;

lispify[Unevaluated[2^4 * 3^2]]


produces

{Times, {Power, 2, 4}, {Power, 3, 2}}

My first try had only one difference, namely

lispify /@ Unevaluated /@ {args}


and sent me down a frustrating rabbit hole until I stumbled on the corrected one above.

Would someone be so kind as to explain the details of both the correct and incorrect solution?

EDIT:

As a minor bonus, this enables a nice way to visualize unevaluated expression trees:

ClearAll[stringulateLisp];
stringulateLisp[l_List] := stringulateLisp /@ l;
stringulateLisp[e_] := ToString[e];
ClearAll[stringTree];
stringTree[l_List] := First[l][Sequence @@ stringTree /@ Rest[l]];
stringTree[e_] := e;
ClearAll[treeForm];
treeForm = TreeForm@*stringTree@*stringulateLisp@*lispify;
treeForm[Unevaluated[2^4 + 3^2]]


• thank you for having the forethought of kindly sharing a link to Vellega's notes notebook about controlling evaluation from a 1999 conference. ive been looking for something like this nearly my entire short wolfram life. although somewhat dated pretty much all of it is still relevant today. :) Commented Apr 5, 2022 at 7:06

You must remember that Unevaluated only "works" when it is the explicit head of an expression. In the non-working format the structure looks like:

TreeForm @ HoldForm[lispify /@ Unevaluated /@ {arg1, arg2}]


Note that Unevaluated does not surround arg1 and arg2 therefore they evaluate prematurely.

Now compare the working structure:

TreeForm @ HoldForm[lispify /@ Unevaluated @ {arg1, arg2}]


Here Unevaluated does surround arg1 and arg2 and evaluation is prevented.

By the way you can show an unevaluated TreeForm by using an additional Unevaluated to compensate for an apparent evaluation leak.

treeForm =
Function[expr, TreeForm @ Unevaluated @ Unevaluated @ expr, HoldFirst]


Test:

2^4*3^2 // treeForm


Also possibly of interest: Converting expressions to "edges" for use in TreePlot, Graph