I thought Table should not evaluate the inner code until it inserts the value. I'm confused by


which outputs {{}, {}} where I would have expected it to match


Compare also with for instance:


where clearly it does not evaluate test[i] before insertion of the table values. What is going on here?

  • $\begingroup$ Indeed it doesn't. Try Table[DownValues[Evaluate@i], {i, {test1, test2}}] instead. $\endgroup$
    – MarcoB
    Commented May 2, 2018 at 16:17
  • $\begingroup$ @MarcoB, so why is the Evaluate necessary? $\endgroup$
    – Kvothe
    Commented May 2, 2018 at 16:23
  • $\begingroup$ see mathematica.stackexchange.com/a/41418/27539. I would say the answer is in the first sentence: Because: "Values of Table variables do not get substituted inside held expressions" (I am not sure why this is the case though) $\endgroup$
    – glS
    Commented May 2, 2018 at 17:01

2 Answers 2


Table does not replace the iteration variable (in the style of Replace) which would "pass" through the Hold. Instead it uses Block, which apparently assigns an OwnValue to the iteration variable. See,


which outputs {{HoldPattern[i] :> 1}, {HoldPattern[i] :> 2}, {HoldPattern[i] :> 3}}. This OwnValue is held by DownValues due to its HoldAll attribute. Thus, we evaluate DownValues[i]. Instead of DownValues[test1] (and DownValues[test2]).

The solution is to use Table[With[{i=i},...] as is discussed in Table doesn't replace inside conditionals (If, Which)

(This also possibly makes this a duplicate by the way. The answers on the other post however do not explain that it Table uses OwnValues which here end up being held.)


The problem is the Attributes alloted to Downvalues are HoldAll and Protected. This is in addition to the HoldAll attribute of Table.

Hence, in the first case, first, Downvalues returns an empty list, which Table takes in to create its own list. So, you get a list of two empty lists.

In the second case, you don't have such an intermediary function which has a HoldAll attribute to begin with.

Edit 1:

Table[DownValues[i], {i, {test1, test2}}] // Trace

This clearly shows, that Downlnvalues[i] never gets substituted by Downvalues[test1] or Downvalues[test2].

Hope this clears things out

  • $\begingroup$ That does not address the whole story. Otherwise I would expect: Table has HoldAll and so all evaluation is halted. Than Table does its thing replaces i and then we have DownValues[test1]. At this point DownValues has HoldAll, but that is what we want. Instead table does not replace i with test1. Does it instead assigns i a value (DownValue? apparently not or we would see that instead as output), this value is then held because of DownValues's HoldAll attribute, and we get the wrong result. Something like that? $\endgroup$
    – Kvothe
    Commented May 2, 2018 at 16:40
  • $\begingroup$ Ah indeed it seems it stores an OwnValue for i. $\endgroup$
    – Kvothe
    Commented May 2, 2018 at 16:41
  • $\begingroup$ but this doesn't explain why Table doesn't substitute the arguments of held expressions, does it? $\endgroup$
    – glS
    Commented May 2, 2018 at 17:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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