# How to define a function reminding of names of the independent variables?

I am using a function with a lot of variables. There are 9 and sometimes more of them. In this case, it is difficult to memorize, which one stays on the, say, fourth position, and which one - on the seventh. I would like to be able to include the variable name into the square brackets of the function as a reminder: what must stay here. For example, let us define a simple function: f(x)=x^2+y^3. Here is its definition:

f[x_,y_]:=x^2+y^3;


One can, however, call it with x=5 and y=7 as follows:

f[(*x=*)5,(*y=*)7]


This way reminds me of what should stay in the first and in the second position inside the square brackets.
This works, but I do not like that it looks cumbersome. For perception, it would be much better, if the (* and *) signs are invisible.

Any idea?

• If you are willing to do the extra typing,have you considered using named options instead of arguments for your function? E.g. f[“x” -> 5, “y” -> 7] Commented Jan 1, 2021 at 15:14
• @CA Trevillian, @m_goldberg, @Jean-Pierre I cordially thank all of you. For the task I am presently fulfilling the solution: f[__]:=x^2+y^3; f[x=5,y=3]  seems to be the most economic. Therefore, I choose this one. However, I like all the solutions you proposed, and I will use them from now on. Thank you. Commented Jan 4, 2021 at 14:20

## 3 Answers

Here’s a couple of interesting methods:

f1[x_,y_]:=With[
{
$x=x/.Equal[$arg_,$val_]:>$val,
$y=y/.Equal[$arg_,$val_]:>$val
},
$x^2+$y^3
]

f2[X_,Y_]:=With[
{
$x=X/.Equal[$arg_,$val_]:>Rule[$arg,$val],$y=Y/.Equal[$arg_,$val_]:>Rule[$arg,$val]
},
ClearAll[$assoc];$a=Association[{$x,$y}];
$a[x]^2+$a[y]^3
]


Both carry the same syntax:

f1[x==5,y==3]
f2[x==5,y==3]

(*52*)
(*52*)


While neither do exactly what you might want to do, each offers a unique aspect that you might be able to pull from!

These methods do fall apart if one or more of the variables has already been assigned globally. Inspired by the answer from user @m_goldberg, find this method:

f3[X_,Y_]:=With[
{
$a=Association[{X,Y}] },$a[x]^2+\$a[y]^3
]

x=4;
y=7;
f3[x->5,y->3]

(*52*)


Which is robust against globally assigned values of the arguments used.

This also does work:

f[__]:=x^2+y^3;

f[x=5,y=3]

(*52*)


As pointed out by @G.Shults, this method, unlike the one above it, is only robust against incoming globally assigned values of the arguments. Due to the use of Set, this method has a direct impact on outgoing globally assigned values of the arguments.

Depending upon your use-case, any of these methods may be found to be the most ideal.

• The f[__] method may be robust against incoming globally assigned values of the arguments, but it has the disastrous side effect of setting new values for those global symbols after function invocation. Commented Jan 6, 2021 at 18:31
• @G.Shults that's absolutely right. See, then, the method above that using a combination of Rule that is then fed into Association, it is here that the method is seemingly robust against incoming and outgoing globally assigned values. This is a good point & I will make note of it! Commented Jan 6, 2021 at 19:27

You can get the behavior you ask for if you define your function to work with an association. The key-value paradigm provides syntax close but not exactly as you describe.

Simple approach

f[a_Association] := a[x]^2 + a[y]^3
f[<|x -> 5, y -> 7|>]


368

Argument keys are not affected by global assignments. Changing the order of the key-value pairs has no effect.

x = 42; f[<|y -> 7, x -> 5|>]


368

Behavior when given bad keys is a little messy.

f[<|a -> 5, b -> 7|>]


Missing["KeyAbsent",x]^2+Missing["KeyAbsent",y]^3

Strict approach

Clear[x,y]
g[a : <|x -> _, y -> _|>] := a[x]^2 + a[y]^3
g[<|x -> 5, y -> 7|>]


368

Order matters.

g[<|y -> 7, x -> 5|>]

g[<|y -> 7, x -> 5|>]


Bad keys simply prevent evaluation.

g[<|a -> 5, b -> 7|>]

g[<|a -> 5, b -> 7|>]


Keys are not protected from global assignments, but evaluation doesn't occur. You could fix this by making the keys strings (e.g., "x" in place of x), but typing strings is more time comsuming.

x = 42; g[<|x -> 5, y -> 7|>]

g[<|42 -> 5, y -> 7|>]

• It’s not clear why your last method fails against global assignment. See, e.g., the last method in my answer that is seemingly robust against global assignment. Commented Jan 3, 2021 at 3:22
• @CATrevillian. It is because the evaluator sees x at argument evaluation time. Commented Jan 3, 2021 at 13:24
• This makes sense. There must be, then, some difference between how Association and Rule are interpreted at the argument evaluation time that I am not aware of. Commented Jan 6, 2021 at 19:33
• @CATrevillian. No, not that. My function f is as protected against global assignments as your function f3. It is because the destructuring pattern used in the definition of g lets the evaluator see the symbols x and y in the global context. Commented Jan 6, 2021 at 23:54

If this is just to help entering values in the correct order (and not to be permanently visible), you can possibly use a Placeholder. Reevaluating phf below will produce the template again: just type phf, select it, right-click and choose Evaluate in Place.

f[x_, y_] := x^2 + y^2
phf = Defer[f[Placeholder[x], Placeholder[y]]]


• This is great. Just a note, in most programming languages / IDE's we call this Intellisense; to get tooltips on the arguments expected for the parameter. This makes coding easy by giving methods the arguments they expect. Commented Jan 2, 2021 at 3:35
• Another note: this in place evaluation can also be performed with keyboard shortcuts. On the Mac, after you type phf you can use either Ctl-Period to invoke Edit > Extend Selection or Shift-Opt-LeftArrow to select the previous word, then type Cmd-Return to invoke Evaluation > Evaluate in Place. I assume there are equivalent keyboard shortcuts on Windows. Commented Jan 6, 2021 at 17:55