5
$\begingroup$

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.

$\endgroup$

1 Answer 1

6
$\begingroup$

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:

enter image description here

$\endgroup$
1
  • $\begingroup$ Perfect, thanks! $\endgroup$
    – Ben
    Nov 28, 2022 at 0:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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