# Confused with HoldForm in Postfix notation

Why does the following code produce different result? In my mental model, they should be the same.

Table[With[{x = i^k}, HoldForm[x]], {k, 1, 5}]
With[{x = i^k}, HoldForm[x]] // Table[#, {k, 1, 5}] &


Output:

{i,i^2,i^3,i^4,i^5}
{i^k,i^k,i^k,i^k,i^k}

-

The difference is because in the second case

With[{x = i^k}, HoldForm[x]] // Table[#, {k, 1, 5}] &


The With expression is evaluated (giving HoldForm[i^k]) before it is substituted inside the placeholder in Table. To prevent thise pre-evaluation wrap it around Unevaluated as follows:

Unevaluated[With[{x = i^k}, HoldForm[x]]] // Table[#, {k, 1, 5}] &


Which gives as before:

{i, i^2, i^3, i^4, i^5}

-
What is the difference between Unevaluated and HoldForm? They seem to be similar intuitively. –  Please don't touch Jan 16 at 7:53
To see the difference try: Head[Unevaluated[f[x]]] vs Head[HoldForm[f[x]]] –  RunnyKine Jan 16 at 7:57
@CodeMocker While Runny's workaround indeed solves your problem, it does not give an insight on why With is evaluated before Table in one case but not in the other. For an explanation, please see my answer. –  István Zachar Jan 16 at 10:24

To be more specific, the difference is not because of the postfix application but because of the pure function (the part with # and &) application:

Table[With[{x = i^k}, HoldForm[x]], {k, 1, 5}] (* no pure function *)
(* ==> {i, i^2, i^3, i^4, i^5} *)

With[{x = i^k}, HoldForm[x]] // (Table[#, {k, 1, 5}] &)  (* postfix pure function *)
(* ==> {i^k, i^k, i^k, i^k, i^k} *)

(Table[#, {k, 1, 5}] &) @ With[{x = i^k}, HoldForm[x]]  (* prefix pure function *)
(* ==> {i^k, i^k, i^k, i^k, i^k} *)


Accordingly, if you simplify your example, and put some Prints in it:

Block[{k = 1}, Print[2]; With[{x = k}, Print[1]; HoldForm@x]]

During evaluation of In[17]:= 2
During evaluation of In[17]:= 1
(* ==> 1 *)

Block[{k = 1}, Print[2]; #] &@With[{x = k}, Print[1]; HoldForm@x]

During evaluation of In[17]:= 1
During evaluation of In[17]:= 2
(* ==> k *)


As you can see, in the last case, the With is evaluated first, not Block, resulting in thus a replacement x -> k, so Block cannot replace x in the second step as there is no x anymore in the expression.

An even more simple example that shows the reversed evaluation sequence for pure function application compared to normal, nested expression evaluation:

(Print[2]; Print[1];)

2
1

(Print[2]; #;) & @ Print[1]; (* or:  Print[1]; // (Print[2]; #;) & *)

1
2

-
I like when you explain things with those Prints. It's very useful method. –  Kuba Jan 16 at 12:55
@Kuba ...and a poor man's debugger :) –  István Zachar Jan 16 at 13:00