Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

Possible Duplicate:
Using pure functions in Table

I have run into a situation that I do not understand when trying to generate a nested list of pure functions. I have the following code.

Table[Function[x, i*x + j], {i, 1, 3}, {j, 1, 4}]

I expected to get a nested list of pure functions, but the values for i and j are not being input. I get

{{Function[x, i x + j], Function[x, i x + j], Function[x, i x + j], 
  Function[x, i x + j]}, {Function[x, i x + j], Function[x, i x + j], 
  Function[x, i x + j], Function[x, i x + j]}, {Function[x, i x + j], 
  Function[x, i x + j], Function[x, i x + j], Function[x, i x + j]}}

What is making this operation fail to behave as I expected?

share|improve this question

marked as duplicate by Mr.Wizard Nov 10 '12 at 8:43

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

add comment

4 Answers

up vote 5 down vote accepted

Function has HoldAll attribute:

Attributes[Function]
(*{HoldAll, Protected}*)

To see that this is the cause,

SetAttributes[f, HoldAll]
Table[
 f[x, i*x + j],
 {i, 1, 3},
 {j, 1, 4}
 ]
(*
{{f[x, i x + j], f[x, i x + j], f[x, i x + j], 
  f[x, i x + j]}, {f[x, i x + j], f[x, i x + j], f[x, i x + j], 
  f[x, i x + j]}, {f[x, i x + j], f[x, i x + j], f[x, i x + j], 
  f[x, i x + j]}}
*)

EDIT: You can either use With to inject the values,

Table[
  With[{i=i,j=j},Function[x, i*x + j]],
  {i, 1, 3},
  {j, 1, 4}
  ] 

or, more perversely,

Table[
  function[x, i*x + j],
  {i, 1, 3},
  {j, 1, 4}
  ] /. function -> Function

or even

Block[{Function},
 Table[
  Function[x, i*x + j],
  {i, 1, 3},
  {j, 1, 4}
  ]
 ]
share|improve this answer
1  
It's probably good to point out that the second and third methods (function -> Function and Block) are safe only if the Function contains an expression that does not evaluate. –  Szabolcs Nov 8 '12 at 20:41
    
@Szabolcs right, they effectively sidestep the HoldAll completely –  acl Nov 8 '12 at 20:44
add comment

Function has attribute HoldAll, which means it doesn't evaluate its arguments.

Table localizes the variables in each iteration much like Block does. This means, it just temporarily gives the variables the value that corresponds to the iteration, and then run the contained code.

So, try

x = 8; Function[i, i x]

and see that you get Function[i, i x], where the x has not been replaced.

Try

Array[{i, j} \[Function] x \[Function] i x + j, {3, 4}]
share|improve this answer
add comment

I encountered this problem myself a while ago. The evaluation order of the Table, which the docs say "usually" has the iterative variable replaced first, is a bit weird here. I suppose that this is a case when they're not replaced first.

However, they are replaced for With. You can use this to your advantage with (get it?) this:

Table[With[{a = i, b = j}, Function[x, a*x + b]], {i, 1, 3}, {j, 1, 4}]

Then:

%[[1, 1]][3]
(* 4 *)
share|improve this answer
2  
you can also do With[{i = i, j = j}, Function[x, i*x + j]] –  acl Nov 8 '12 at 20:29
add comment

You already have 3 answers including one accepted one. Notwithstanding, naively I would have done

Table[Function[x, i*x + j // Evaluate], {i, 1, 3}, {j, 1, 4}]

which works and follows your syntax.

PS: I replaced Release by Evaluate to avoid unnecessary confusion.

share|improve this answer
    
That's an interesting tactic. Do you think ReleaseHold would work? My Mathematica 8 help tells me that Release was superseded by Evaluate and ReleaseHold. –  Carl Morris Nov 8 '12 at 22:08
1  
I didn't know the function Release. Apparently it's the old and deprecated name for Evaluate. @Carl Evaluate will work only at the first level of the head with a Hold... attribute. Function[x, i*x + j // Evaluate] will work here, but Function[x, Evaluate[i]*x + Evaluate[j]] will not. This is because Evaluate is implemented as a special exception to Hold... attributes: when the evaluator sees something with HoldAll, it will check if there's an Evaluate inside, but only at the first level (it won't do a potentially slow deep search). –  Szabolcs Nov 8 '12 at 22:23
1  
@Szabolcs, as I said a number of times before, Release[] is a sort of hybrid of Evaluate[] and ReleaseHold[]; that is, it was the useful function before the devs at Wolfram finally decided to split Release[]'s functionality into the two modern functions Evaluate[] and ReleaseHold[]. –  J. M. Nov 8 '12 at 23:29
add comment

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