Table[If[cond, y], {y, 1, 3}]

outputs this:

{If[cond, y], If[cond, y], If[cond, y]}

The y is not replaced by its value, as is normally the case with Table[]. This also happens with Which[].

How do I get Table to actually replace the values for y? Why does this happen?


While investigating to document the question i found the solution:


Because: "Values of Table variables do not get substituted inside held expressions" and If has the Attribute HoldRest and Which has HoldAll:

In[1]:= Attributes[Which]

Out[1]= {HoldAll, Protected}

Out[2]= {HoldRest, Protected}

How to "fix" it?

Using With:

Table[With[{y = y}, If[cond, y]], {y, 1, 3}]

This behavior is further illustrated by this example from the "Possible issues" section from the Table documentation:

Values of Table variables do not get substituted inside held expressions:

In[1]:= Table[Hold[i], {i, 5}]

Out[1]= {Hold[i], Hold[i], Hold[i], Hold[i], Hold[i]}

Use With to insert values:

In[2]:= Table[With[{i = i}, Hold[i]], {i, 5}]

Out[2]= {Hold[1], Hold[2], Hold[3], Hold[4], Hold[5]}
  • $\begingroup$ It's strange that there are no documented cases of this happening(in forums or stackexchange) , since both If and Tableare commonly used functions, and most basic users don't know about the existence of the Hold attributes. I myself discovered this by error, never even imagined that if had a HoldRest. $\endgroup$ – dmal Jan 30 '14 at 17:04
  • $\begingroup$ Please see the duplicate link above. This is a documented and expected behaviour of If. The answer in the link also goes in to some discussion on why If must have this attribute. It is true that basic users won't know about the hold attributes, but I suppose that's part of learning a language... at some point you'll hit a "strange behaviour" which teaches you something new :) $\endgroup$ – rm -rf Jan 30 '14 at 17:10

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