# When does Slot evaluate?

I looked up the related answers, it must have to do with the scope. Toy example similar to mine in structure:

foo[i_] := Array [If[Slot[1] == Slot[i + 1], 0, 1] &, ConstantArray[2, 3]];


Fail: in bar[1], Slot[1+1] does not compute. I hotfixed it by using

List[##][[i+1]]


instead of the 2nd Slot and it works as intended. Of course I can apply generous Where, With etc. statements instead like suggested in the other answers, but I'm just curious: When does Slot goes on Hold? Do other constructs than Slot have the same problem?

• You can use With to make sure i+1 gets evaluated before entering Slot: foo[i_] := With[{j = i + 1}, Array[If[Slot[1] == Slot[j], 0, 1] &, ConstantArray[2,3]] ]; Commented Mar 5, 2018 at 16:27
• Ah, I missed your remark about With. Still, for the benefit of readers who don't know how to use With. Commented Mar 5, 2018 at 16:33

I'm guessing that this has more to do with Function than with Slot. If you look at the attributes of Function and Slot, you'll notice that Function is HoldAll while Slot is NHoldAll.

Attributes[Function]
Attributes[Slot]

Out[23]= {HoldAll, Protected}

Out[24]= {NHoldAll, Protected}


Since this behaviour doesn't have anything to do with N, NHoldAll isn't really relevant. Slot by itself can never distinguish between 2 and 1+1 since the sum would always evaluated before Slot sees it.

However, Function is HoldAll and my guess is that it scans the body of the function (without evaluating it) for patterns of the form Slot[_Integer] (or other allowed forms like Slot[_String] for Associations) and inserts the function arguments appropriately. Since Slot[1+1] does not match Slot[_Integer], Function cannot replace that slot with an argument and complains.

So my mental model of Function is:

1. Scan body for occurrences of Slot. Nothing gets evaluated in this stage
2. Replace Slots with arguments of the function
3. Evaluate body after the replacements
• I think evaluating Slot[0+1] and Slot[0+1]&corroborates your point Commented Mar 5, 2018 at 18:00