9
$\begingroup$

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]]

Mathematica graphics

$\endgroup$
8
$\begingroup$

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}]

enter image description here

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

Now compare the working structure:

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

enter image description here

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

See also:


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

enter image description here

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

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.