# Using a list of tuples in a pure function

I want to use a list of tuples within a function to make assignments.

Say I want to make assignments of the form

value[i,j] = val


What I have is a list of tuples that give the relevant indices (i,j):

tuples = {{i[1],j[1]},{i[1],j[2]}, ... , {i[imax],j[jmax]}}


What I have found is that this statement will work in Mathematica 8 :

Function[t, value[t[[1]], t[[2]]] = 0.] /@ tuples


But using slots does somehow not work:

value[#[[1]],#[[2]]] = 0. & /@ tuples


... gives an error.

Where is the mistake I am making or is there no way to do this using slots? (using Part[#,1] and Part[#,2] will not help either]?

It is good practice to check the precedence of code that is not behaving as you expect.

• One of the easiest ways to do this is to use Ctrl+. to expand the selection outward from the cursor while respecting Mathematica precedence.

• Converting the expression to StandardForm (Ctrl+Shift+N) will often reveal something about the way Mathematica is parsing your code.

• Explicitly parenthesize the code using group, supplied below.

• Wrapping the code with HoldForm[FullForm[ . . . ]] (or appending // FullForm // HoldForm) is a robust but harder to read way to check exactly what Mathematica makes of your code.

• In this case syntax highlighting should also tell you that something may be wrong, but the highlighting is not entirely reliable. (It may show errors on some correct code.)

• As a last resort if other methods fail e.g. because your code has syntax errors you can use UndocumentedTestFEParserPacket to see how the Front End is parsing it. Example:

In the image below I have converted to StandardForm and also used Ctrl+. to expand the selection. You can see that Mathematica is parsing your Function as (0. &) and that the Map operation is being done before the Set operation.

A function to explicitly parenthesize code:

SetAttributes[group, HoldFirst]

group[expr_] :=
Replace[
Unevaluated[expr],
x : _[___] :>
RawBoxes @ RowBox[{"(", ToBoxes @ Unevaluated @ x, ")"}],
{0, -1}
];


Applied to your case:

group[
value[#[[1]], #[[2]]] = 0. & /@ tuples
]

((value[((#1)[[1]]), ((#1)[[2]])]) = ((0. &) /@ tuples))

• This may be easier to read than the FullForm as it tends to expand code less.
• The output of group is valid input which may be used as-is or modified.
• I am going to use ctrl-. more! I didn't know it's precedence-aware'that's quite useful. I mostly use ctrl-shift-B to extend my selection and check the balance at the same time. Mar 18, 2012 at 20:50
• @gwr Thanking anyone who answered is nice, but don't feel it as a being a requirement: meta.stackexchange.com/questions/17878/… Mar 18, 2012 at 20:57

This is a precedence issue: You may use

(value[#[[1]], #[[2]]] = 0.) & /@ tuples


instead (ie, explicitly indicate precedence by using brackets).

One way to see what is going on is to notice the colour of the # in the notebook. Or select the & symbol, then press Ctrl+. repeatedly. This progressively selects larger chunks of the expression to which the currently selected expression belongs, and does so in order of precedence. You then will see that 0. & /@ tuples is what mma sees.

You can also use

Trace[value[#[[1]], #[[2]]] = 0. & /@ tuples]


and notice that at some point mma tries to evaluate

value[#1[[1]], #1[[2]]] = {0., 0., 0.}


which is what gives the error (and is due to the precedence issue described above, as it is the result of 0.&/@tuples; tuples is set to a list of three pairs in my case).

• I am on the wrong side of this today. I didn't know you were going to expand your answer. Mar 18, 2012 at 12:27
• @Mr.Wizard Thank you for discreetly telling me off :) But, in all seriousness, I simply did not think of saying anything other than "add brackets" in the beginning, and then changed my mind. It also annoys me when this happens to me.
– acl
Mar 18, 2012 at 12:33
• I am not telling you off! I am instead amused by the fact that something I supported (which I try not to do as often now) surprised me. I started to make my post an edit to yours, but as it grew longer I decided to post it separately. Mar 18, 2012 at 12:37