Variables in Pure Functions and Rules

Module and With allow you to give a specific list of symbols whose names you want to treat as local. In some situations, however, you want to automatically treat certain symbol names as local.

For example, if you use a pure function such as Function[{x},x+a], you want x to be treated as a "formal parameter", whose specific name is local. The same is true of the x that appears in a rule like f[x_]->x^2, or a definition like f[x_]:=x^2.

The Wolfram Language uses a uniform scheme to make sure that the names of formal parameters that 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.

Here is a nested pure function:
Click for copyable input
The Wolfram Language renames the formal parameter y in the inner function to avoid conflict with the global object y:
Click for copyable input
The resulting pure function behaves as it should:
Click for copyable input

In general, the Wolfram Language renames the formal parameters in an object like Function[vars,body] whenever body is modified in any way by the action of another pure function.

The formal parameter y is renamed because the body of the inner pure function was changed:
Click for copyable input
Since the body of the inner function does not change, the formal parameter is not renamed:
Click for copyable input

The Wolfram Language 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, the Wolfram Language still renames formal parameters even in such cases.

In this case, the formal parameter x in the inner function shields the body of the function, so no renaming is needed:
Click for copyable input
Here are three nested functions:
Click for copyable input
Both inner functions are renamed in this case:
Click for copyable input

As mentioned in "Pure Functions", pure functions in the Wolfram Language are like expressions in formal logic. The renaming of formal parameters allows Wolfram Language pure functions to reproduce all the semantics of standard expressions faithfully.

Function[{x,},body]local parameters
lhs->rhs and lhs:>rhslocal pattern names
lhs=rhs and lhs:=rhslocal pattern names
With[{x=x0,},body]local constants
Module[{x,},body]local variables

Scoping constructs in the Wolfram Language.

The Wolfram Language has several "scoping constructs" in which certain names are treated as local. When you mix these constructs in any way, the Wolfram Language does appropriate renamings to avoid conflicts.

The Wolfram Language renames the formal parameter of the pure function to avoid a conflict:
Click for copyable input
Here the local constant in the inner With is renamed to avoid a conflict:
Click for copyable input
There is no conflict between names in this case, so no renaming is done:
Click for copyable input
The local variable y in the module is renamed to avoid a conflict:
Click for copyable input
If you execute the module, however, the local variable is renamed again to make its name unique:
Click for copyable input

The Wolfram Language treats transformation rules as scoping constructs, in which the names you give to patterns are local. You can set up named patterns either using x_, x__, and so on, or using x:patt.

The x in the h goes with the x_, and is considered local to the rule:
Click for copyable input

In a rule like f[x_]->x+y, the x that appears on the righthand side goes with the name of the x_ pattern. As a result, this x is treated as a variable local to the rule, and cannot be modified by other scoping constructs.

The y, on the other hand, is not local to the rule, and can be modified by other scoping constructs. When this happens, the Wolfram Language renames the patterns in the rule to prevent the possibility of a conflict.

The Wolfram Language renames the x in the rule to prevent a conflict:
Click for copyable input

When you use With on a scoping construct, the Wolfram Language automatically performs appropriate renamings. In some cases, however, you may want to make substitutions inside scoping constructs, without any renaming. You can do this using the /. operator.

When you substitute for y using With, the x in the pure function is renamed to prevent a conflict:
Click for copyable input
If you use /. rather than With, no such renaming is done:
Click for copyable input

When you apply a rule such as f[x_]->rhs, or use a definition such as f[x_]:=rhs, the Wolfram Language implicitly has to substitute for x everywhere in the expression rhs. It effectively does this using the /. operator. As a result, such substitution does not respect scoping constructs. However, when the insides of a scoping construct are modified by the substitution, the other variables in the scoping construct are renamed.

This defines a function for creating pure functions:
Click for copyable input
The x and x^2 are explicitly inserted into the pure function, effectively by using the /. operator:
Click for copyable input
This defines a function that creates a pair of nested pure functions:
Click for copyable input
The x in the outer pure function is renamed in this case:
Click for copyable input