# How to correctly specify variables in a function? [duplicate]

There is an expression

(Sqrt[\[Pi]] (a b^2 d^3 + a (b^2 d^3 + 2 a (b + b d^3))) r[1, 1] r[1, 4])/(2 c^2 (b + b d^3)^(3/2)) - ( Sqrt[\[Pi]] (a b^2 d^4 + a (b^2 d^4 + 2 c (b d + b d^3))) r[5, 2] r[ 1, 4])/(2 a^2 (b d + b c^3)^(3/2))

where a, b, c, d, r[1, 1], r[1, 4], r[5, 2] are variables.

I would like to write this expression as a function f where a, b, c, d, r[1, 1], r[1, 4], r[5, 2] are variables. It can be indicated that a, b, c and d are variables as follows f[a_,b_,c_,d_]:= the expression, but how can I specify that r[1, 1], r[1, 4] and r[5, 2] are also variables f[a_,b_,c_,d_,...]:= the expression?

• Simplest: f[a_,b_,c_,d_,r_]:= the expression.
– Alan
May 19, 2023 at 14:00
• @Alan, the variables r[1, 1], r[1, 4], r[5, 2] and r[1, 4] have different values May 19, 2023 at 14:08
• To be more specific, my allowNonSymbol therein is exactly for the task. May 19, 2023 at 14:25
• You list r[1, 4] twice in each of the four variable lists; the last time, in a comment, you give it two different values. Why? How can the same expression have two different values simulataneously? Is it a mistake? May 19, 2023 at 16:26
• With @Alan's suggestion, call f thus: f[1,2,1,1, <|1 -> <|1 -> 2, 4 -> 3 (* or 6 *)|>, 5 -> <|2 -> 5|>|>]. May 19, 2023 at 17:04

I'm pretty sure I'm misunderstanding something, so this isn't so much an answer as an attempt to force more clarity.

Here is a function:

theFunction[arg1_, arg2_, arg3_, arg4_, arg5_, arg6_, arg7_] :=
((arg1*arg2^2*arg4^3 + arg1*(arg2^2*arg4^3 + 2*arg1*(arg2 + arg2*arg4^3)))*arg5*arg6*Sqrt[Pi])/
(2*arg3^2*(arg2 + arg2*arg4^3)^(3/2)) -
((arg1*arg2^2*arg4^4 + arg1*(arg2^2*arg4^4 + 2*arg3*(arg2*arg4 + arg2*arg4^3)))*arg6*arg7*Sqrt[Pi])/
(2*arg1^2*(arg2*arg3^3 + arg2*arg4)^(3/2))


Applying the function as follows will reproduce your original expression:

theFunction[a, b, c, d, r[1, 1], r[1, 4], r[5, 2]]


And so, in the specific example you gave in one of your comments:

theFunction[1, 2, 1, 1, 2, 3, 5]
(* -9*Sqrt[Pi] *)


Is that what you're after?

• It's not, I'm afraid. See the suggested duplicate above. May 19, 2023 at 15:17
• @lericr, thanks for this answer! I'll try to use it (simply redefine all variables of this type r[..., ...] to regular string variables. May 19, 2023 at 16:44
• @MamMam - expr = <your expression>; param = {a, b, c, d, r[1, 1], r[1, 4], r[5, 2]}; f = Function @@ ({param, expr} /. {r[1, 1] -> r11, r[1, 4] -> r14, r[5, 2] -> r52}) May 20, 2023 at 21:07

Using r essentially as a private keyword is dangerous, if r is not protected. For instance, setting r = 7 will generally mess up any code that assumes r is an undefined symbol. You can Protect it, which will protect your code from most bugs, but Protect can be overridden. (There is also Locked, if you want, then the following won't work.)

That aside, assuming r is safe but not protected:

ClearAll[f];
f[a_, b_, c_, d_, r11_, r14_, r52_] := Block[{r},
(*Unprotect[r];*)  (* uncomment if r is protected *)
r[1, 1] = r11; r[1, 4] = r14; r[5, 2] = r52;
(*Protect[r];*)    (* uncomment if r is protected *)
(* OP's expression *)
(Sqrt[\[Pi]] (a b^2 d^3 + a (b^2 d^3 + 2 a (b + b d^3))) r[1, 1] r[
1, 4])/(2 c^2 (b + b d^3)^(3/2)) - (Sqrt[\[Pi]] (a b^2 d^4 +
a (b^2 d^4 + 2 c (b d + b d^3))) r[5, 2] r[1,
4])/(2 a^2 (b d + b c^3)^(3/2))
];

f[1, 2, 1, 1, 2, 3, 5]
(*  -9 Sqrt[\[Pi]]  *)


Again, I will point out that we're assuming it is safe to treat Globalr as a reserved keyword. If this is combined with other code that uses r in a different way, you may find you have bugs. I offer this answer in the spirit of showing the difficulties of using a tool (Mma) in ways it wasn't really designed for. It would be better practice to rewrite your r variables as r11, r14, r52, which is essentially what @lericr's answer recommends.

• Thanks for this answer! Yes, I agree with that this is a good way to redefine variables May 19, 2023 at 17:53
• @MamMam One could use Module instead of Block and then r is properly localized. I was originally thinking that the expression was pre-defined and r had to be global. But looking at how it is coded above, the expression is, and needs to be, explicitly in the body of the function. I should have used Module` in hindsight. May 19, 2023 at 17:56
• Thanks for the comment! May 19, 2023 at 19:27