# Order of operations for the Table function [duplicate]

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?

-

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

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}
]
]

-
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

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}]

-

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 *)

-
you can also do With[{i = i, j = j}, Function[x, i*x + j]] –  acl Nov 8 '12 at 20:29

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.

-
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
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
@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[]. –  Guess who it is. Nov 8 '12 at 23:29