6

How does one manipulate the slot numbers in a pure function? Some trick with Evaluate or Hold? I'm aiming for something along the lines of:

(Slot /@ Range[19, 164, 29])& @@ {...}

EDIT

It turns out my actual problem is: why does

Evaluate[{Slot /@ Range[19, 164, 29]}] & @@ Range[164]

yield {{19, 48, 77, 106, 135, 164}} but

{Evaluate[Slot /@ Range[19, 164, 29]]} & @@ Range[164]

yields {{#19, #48, #77, #106, #135, #164}}?

mfvonh
  • 8,460
  • 27
  • 42

2 Answers2

12

Responding to your updated question, which should probably be closed as a duplicate once someone takes the time to find the original: Evaluate only works when it is the explicit head of an argument. In other words Evaluate[ . . . ] must appear as one of the arguments of the Head who's Hold attribute you wish to override. You should read this paper, which teaches this among many other useful things:

As an example consider these lines:

Hold[1 + 1, Evaluate[2 + 2]]
Hold[1 + 1, {Evaluate[2 + 2]}]
Hold[1 + 1, Evaluate @@ {2 + 2}]
Hold[1 + 1, 4]

Hold[1 + 1, {Evaluate[2 + 2]}]

Hold[1 + 1, Evaluate @@ {2 + 2}]

Note that only the first form evaluates. On lines two and three the Heads of the second arguments are List and Apply rather than Evaluate.

A common method to get around this is to use With to inject an expression into the body of the function:

With[{body = Slot /@ Range[19, 164, 29]}, {body} &]

% @@ Range[164]
{{#19, #48, #77, #106, #135, #164}} &

{{19, 48, 77, 106, 135, 164}}

If you want to evaluate the entire body every time you can just Apply Function to a List of the components that form the Function:

(Function @@ {{Slot /@ Range[19, 164, 29]}}) @@ Range[164]
{{19, 48, 77, 106, 135, 164}}
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
3

E.g.,

Evaluate[Slot /@ Range[1, 5, 2]] & @@ {1, 2, a, 4, 5, 6, 7}

(*  {1,a,5}  *)
ciao
  • 25,774
  • 2
  • 58
  • 139
  • Thanks for the reply. It made me realize I wasn't asking the right question; I've edited the post. – mfvonh Apr 25 '14 at 01:04
  • @mfvonh: Look at the FullForm of each. One produces a function with a list of slots, the other produces a function with a list with only one entry: Evaluate[Map[Slot, Range[19, 164, 29]]] giving you the list of unevaluated slots... – ciao Apr 25 '14 at 01:15