0
$\begingroup$

From the documentation of Function, I take this example (slightly simplified). Renaming the dummy or bound variable (y->y$ in the inner Function) is necessary in:

In[1206]:= Function[x, Function[y, f[x, y]]][y]
Out[1206]= Function[y$, f[y, y$]]

so that, for example,

In[1215]:= Function[x, Function[y, f[x, y]]][y][1]
Out[1215]= f[y, 1]

because

In[1211]:= Function[y$, f[y, y$]][1]
Out[1211]= f[y, 1]

Without renaming, we would obtain a different and generally wrong value

In[1212]:= Function[y, f[y, y]][1]
Out[1212]= f[1, 1]

The documentation shows that renaming occurs even if it is not necessary:

In[1213]:= Function[x, Function[y, f[x, y]]][1]
Out[1213]= Function[y$, f[1, y$]]

Indeed, the choice of parameter name y should have no consequence on the function value.

Now let me try:

 In[1214]:= Function[x, Function[y, f[x, y]]][y$]
 Out[1214]= Function[y$, f[y$, y$]]

which is the same as Function[y, f[y, y]] that is wrong, as explained above.

So it looks to me like a plain fat bug, is not it?

Edited after comments

The bug is equivalent to:

In[1335]:= With[{x = y$}, Function[y, f[x, y]]]
Out[1335]= Function[y$, f[y$, y$]]

In this related case on the contrary no renaming occurs:

In[1338]:= Function[y, f[x, y]] /. x -> y$
Out[1338]= Function[y, f[y$, y]]

That is because the job of ReplaceAll is just to replace, not to detect name conflict.

$\endgroup$
6
  • 3
    $\begingroup$ It's been there, probably since the beginning, but at least since v2, when I used the same "trick" as in your last example to solve a programming problem I didn't understand until I had been on this site for a couple of years — a long time spent in ignorance. I was always worried that they would change the renaming convention to use Unique or some such thing that couldn't be hacked. But the simple rule is, "Don't ever end your variables with a $." (A similar renaming occurs in DynamicModule, but with $$.) $\endgroup$
    – Michael E2
    Dec 28, 2021 at 17:10
  • $\begingroup$ Fortunately no problem with y$$. So a remaining question is: is this the only case of automatic renaming by appending a single \$? If so, avoiding single \$-ending names will be relatively safe. I had in mind that Block was using internally single \$-ending name but I can't prove it so I was probably mistaken. $\endgroup$ Dec 28, 2021 at 18:09
  • 1
    $\begingroup$ There's an extensive discussion of renaming in the tutorial "Modularity and the Naming of Things", esp. this section. Block[] does not rename variables. Module[] and DynamicModule[] rename variables, but they use a different mechanism than the one you're discussing. $\endgroup$
    – Michael E2
    Dec 28, 2021 at 18:19
  • 3
    $\begingroup$ You can search on site for "lexical scoping" to see some discussion and how to solve various problems. This might be the most relevant here, but there are others: mathematica.stackexchange.com/questions/119403/… $\endgroup$
    – Michael E2
    Dec 28, 2021 at 18:23
  • $\begingroup$ The no single $ ended name rule can be formally backed by this case Function[t, Function[u$, t + u$]]@u$ where name conflict should be resolved by u$$ but is not. Amazingly, Function[t, Function[u$$, t + u$$]]@u$$ resolves name conflict with u$$$. This is weird. $\endgroup$ Jan 4, 2022 at 11:26

2 Answers 2

1
$\begingroup$

If you use $ signs at the end of variable names in Function in Manipulate, you're asking for trouble.

Manipulate[
 Function[x, Function[y, f[x, y$]]][y$$],
 {y, 0, 1}]
Manipulate[
 y$$$ + y$$$$ + y$$$$$ + Function[x, Function[y, f[x, y]]][y$$],
 {y$$$$$, 1, 2}]
Manipulate[
 y$$$ + y$$$$ + y$$$$$ + Function[x, Function[y, f[x, y]]][y$$$],
 {y$$$$$, 1, 2}]

The explanation is that Manipulate strips and adds dollar signs according to its own secret rules, maybe after thumb wrestling with Function, which is not really an explanation. The results always seem to be the same. Maybe not from version to version. I didn't check.

$\endgroup$
0
$\begingroup$

From the documentation of Function in Mathematica:

The named formal parameters Subscript[x, i] in Function[{Subscript[x, 1],\[Ellipsis]},body] are treated as local, and are renamed Subscript[x, i]$ when necessary to avoid confusion with actual arguments supplied to the function.

One missing information in this laconic description is that single \$-ended formal parameters, corresponding to the string expression ___ ~~ Except@"$" ~~ "$", e. g. t$, but not t$$, are never renamed.

The renaming mechanism (called α-conversion in λ-calculus) appears in the minimal case

In[3]:= Function[t, Function[u, y[t, u]]]@v
Out[3]= Function[u$, y[v, u$]]

Semantically, for a faithful model of a mathematical (partial) function, renaming is only needed if the value of v is u (v==u):

In[4]:= Function[t, Function[u, y[t, u]]]@u
Out[4]= Function[u$, y[u, u$]]

The Wolfram language model of function is thus overcautious. For example, renaming occurs without need in

In[7]:= Function[t, Function[u, y[t, u]]]@1
Out[7]= Function[u$, y[1, u$]]

I suppose that this overcautiousness is intended by design to save the test u==v run time.

If ever you want to avoid unneeded renaming, you can, by using single \$-ended in the first place:

In[9]:= Function[t, Function[u$, y[t, u$]]]@1
Out[9]= Function[u$, y[1, u$]]

Thus Michael E2's rule "Don't ever end your variables with a \$." is safe but also overcautious for the following reasons:

  1. Single \$-ended names are useful (or intended by design) to avoid renaming.
  2. Names ending with at least two \$ like t$$ are perfectly safe for Function (although elsewhere I can't assert).
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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