0
$\begingroup$

I evaluated

Table[#[[i]] &, {i, 1, 5}]

and got

{#1[[i]] &, #1[[i]] &, #1[[i]] &, #1[[i]] &, #1[[i]] &}

what I did expect was

{#1[[1]] &, #1[[2]] &, #1[[3]] &, #1[[4]] &, #1[[5]] &}

I always assumed Table would just replace the expression with a list of replacement rules similar to what ReplaceAll would do given a list of rules.

ReplaceAll[#[[i]] &, {Thread[i->Range[5]]}//Transpose]

which gives

{#1[[1]] &, #1[[2]] &, #1[[3]] &, #1[[4]] &, #1[[5]] &}

Can someone please explain the difference?

$\endgroup$
3
  • $\begingroup$ "Table evaluates its arguments in a nonstandard way...". Straight from the documentation. You know, that thing with lots of letters and words that tells how things work. The details are there. $\endgroup$
    – ciao
    Mar 5, 2015 at 8:06
  • $\begingroup$ @Nasser in this case it is because Function // Attributes not Table's. But I agree this question should be closed, probably as a duplicate. $\endgroup$
    – Kuba
    Mar 5, 2015 at 8:15
  • $\begingroup$ I was not aware of the question linked above and I agree that my question is a duplicate. However, unfortunately I still do not understand why the attributes of Function prevent the replacement of i. I can replace inside held expressions just fine like #[[i]] & /. i -> 1. Table has the HoldAll attribute as Nasser and rasher pointed out. But ReplaceAll[ Unevaluated[#[[i]] &], {Thread[i -> Range[5]]} // Transpose] still yields the result with the i's replaced. Where is the difference between my approach and Table? $\endgroup$
    – Max1
    Mar 5, 2015 at 9:21

1 Answer 1

1
$\begingroup$

This is due to the HoldAll Attribute of Function. This can be demonstrated by temporarily clearing this attribute as follows:

Internal`InheritedBlock[
  {Function},
  ClearAttributes[Function, HoldAll];
  Table[#[[i]] &, {i, 1, 5}]
  ] // Quiet

{1 &, #1[[2]] &, #1[[3]] &, #1[[4]] &, #1[[5]] &}

You can find statements regarding the Attributes for Function under the Details section in the Documentation.

This is based on the the following: What are the use cases for different scoping constructs?

$\endgroup$
4
  • $\begingroup$ Thanks, this shows that the HoldAll attribute is certainly important in this case. The replacement mechanism of Table, however, is not yet clear to me. Could you maybe give a toy-implementation of a Table function which behaves like the built-in function using some other functions? $\endgroup$
    – Max1
    Mar 5, 2015 at 9:58
  • 1
    $\begingroup$ @Max1 Table is not replacing in this sense. It does something like: i = 2; Hold[i] +*scoping*, which can't get into held expressions. $\endgroup$
    – Kuba
    Mar 5, 2015 at 10:11
  • 1
    $\begingroup$ If you follow the above link "What... scoping constructs?", you will find a table-like function constructed using Reap and Sow. $\endgroup$ Mar 5, 2015 at 10:25
  • $\begingroup$ @Kuba That's the answer I was looking for :) The link provided by zentient was also very helpful. I think my main problem was that I did not properly understand the way functions like Table localize their arguments and thus assmued some kind of replacement inside the held expression should happen. The section "Implementing functions that localize their arguments" in the linked answer made it clear what really happens (atleast as a mental model of what happens). $\endgroup$
    – Max1
    Mar 5, 2015 at 12:07

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