Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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}
share|improve this question

2 Answers 2

up vote 2 down vote accepted

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}

share|improve this answer
    
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
share|improve this answer
    
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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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