# Automatic scoping of input to function

I'd like to write a function whose arguments contains symbols that are automatically localized, just like some built-in functions, like Sum. Even better, I'd like to see the symbols' color change, to remind the user about the localization.

For example, if I wanted to do matrix multiplication in tensor notation, where the specified index is summed over the specified coordinates, I would use

SetAttributes[contractIndices, HoldAll]
contractIndices[expr_, dummyindices_List, coordinates_List] :=
Module[{result = Hold[expr]},
Do[result = Sum[result /. {a -> coord}, {coord, coordinates}], {a,
dummyindices}];
ReleaseHold[result]]


and expect

contractIndices[f[i, j] g[j, k], {j}, {x, y, z}]


to return

f[i,x] g[x,k] + f[i,y] g[y,k] + f[i,z] g[z,k]


even if the symbol j had been given a value previously.

Of course I could simply always enclose this inside a Module[{j},...], but I want a function that automatically localizes, just as Sum does with its dummy variable.

This can be done quite easily using Block and SyntaxInformation:

SetAttributes[contractIndices, HoldAll]
contractIndices[expr_, dummyindices_List, coordinates_List] :=
Block[
dummyindices,
Module[{result = Hold[expr]},
Do[result = Sum[result /. {a -> coord}, {coord, coordinates}], {a,
dummyindices}];
ReleaseHold[result]]
]

SyntaxInformation[
contractIndices] = {"ArgumentsPattern" -> {_, {___}, {___}},
"LocalVariables" -> {"Solve", {2, 2}}};

j = 2; (* to demonstrate successful localization *)
contractIndices[f[i, j] g[j, k], {j}, {x, y, z}]
(* f[i, x] g[x, k] + f[i, y] g[y, k] + f[i, z] g[z, k] *)


The localization is very close to what you suggested using Module, we simply do it inside the function and use Block. The reason I use block is that "Block-like" localization is what is used for Sum, Table, etc., so it felt the most natural here.

The highlighting is done using SyntaxInformation. The help is a bit vague and your possibilities are quite limited, but luckily Solve-type localization gives the correct coloring:

• Perfect, thanks!
– Ben
Nov 28, 2022 at 0:45