From: David on
Hello everyone :-)

This topic is about nested pure functions and the local parameters
that they use.

I'll start by quoting the Mathematica Book version 5, page 385:

"Mathematica uses a uniform scheme to make sure that the names of
formal parameters which appear
in constructs like pure functions and rules are kept local, and are
never confused with global names.
The basic idea is to replace formal parameters when necessary by
symbols with names of the form
x$. By convention, x$ is never used as a global name."

The following example is then shown:

In[1]:= Function[{x}, Function[{y}, x + y]]
Out[1]= Function[{x}, Function[{y}, x + y]]

In[2]:= %[2y]
Out[2]= Function[{y$}, 2 y + y$]

Here we can clearly see what happens. Since global variables are
introduced into the body if the pure function with a parameter "y", it
needs to change its name to separate itself from the global "y". We
can see that the local "y" is renamed to "y$".

Here is another quote from the Mathematica book from the same page:

"Mathematica renames formal parameters in pure functions more
liberally than is strictly necessary.
In principle, renaming could be avoided if the names of the formal
parameters in a particular function
do not actually conflict with parts of expressions substituted into
the body of the pure function. For
uniformity, however, Mathematica still renames formal parameters even
in such cases."

So, whenever the body of a pure function is changed because of a
substitution, Mathematica renames all local parameters in the body of
the function. This made me experiment a bit:

In[1]:= func = Function[{x}, Function[{y}, Function[{z}, x + y + z]]]
Out[1]= Function[{x}, Function[{y}, Function[{z}, x + y + z]]]

In[2]:= func[a][b][c]
Out[2]= a + b + c

So far, everything is fine and dandy. Let's try to make it "fail".

In[3]:= func[a]
Out[3]= Function[{y$}, Function[{z$}, a + y$ + z$]]

We can see that the local parameters have been renamed.
Now try this:

In[4]:= %[z$]
Out[4]= Function[{z$}, a + z$ + z$]

Uh oh, can you see where this is going?

In[5]:= %[a]
Out[5]= 3 a

So, it seems we can easily bypass Mathematica's way of trying to
prevent substitutions into pure functions from interfering with formal
local parameters. Why doesn't Mathematica further rename the z$
variable to e.g. z$1 or something similar after the second
substitution?
I kind of expected the following answer:

Out[5]= 2 a + z$

And before someone tells me I already answered the question in my own
post; I am fully aware that the first quote from the book said the
following: "By convention, x$ is never used as a global name."

So, it is simply _expected_ to not use such variables?

I'll leave you with this:

In[6]:= func[y$][z$][a]
Out[6]= 3 a

Discuss.