# Exhaustive examples of variable replacement due to nested scoping constructs

Consider the following examples, where I have replaced dollar signs in the output by a D.

3/.x_:> Rule[var_,x]
3/.x_:> RuleDelayed[var_,x]
3/.x_:> Function[var, x]
3/.x_:> Hold[Compile[{var, _Integer}, x]]
3/.x_:> Hold[SetDelayed[var_, x]]
3/.x_:> Hold[Set[var_,x]]
3/.x_:> Hold[TagSet[2,var_,x]]
3/.x_:> Hold[UpSet[var_,x]]
3/.x_:> Hold[UpSetDelayed[var_, x]]
3/.x_:> Hold[TagSetDelayed[2, var_, x]]
3/.x_:> Hold[With[{var=b},x]]
3/.x_:> Hold[Module[{var=b},x]]

(*not Block*)
(*3/.x_:> Hold[Block[{var=b},x]]*)
(*not DynamicModule*)
(*3/.x_:> ToString@Hold[DynamicModule[{var=b},x]]*)
(*not the Table family*)
(*3 /. x_ :> Hold[Table[x, {var, 5}]] *)

Function[x,Condition[var_,x]][3] (*ReplaceAll interacts with Condition, so I use Function*)

(*not RuleCondition*)
(*Function[x, Hold[RuleCondition[var_, x]]][3]*)

varD_->3
varD_:>3
Function[varD,3]
Hold[Compile[{varD,_Integer},3]]
Hold[varD_:=3]
Hold[varD_=3]
Hold[2/:varD_=3]
Hold[varD_^=3]
Hold[varD_^:=3]
Hold[2/:varD_:=3]
Hold[With[{varD=b},3]]
Hold[Module[{varD=b},3]]
varD_/;3


and these ones

{"Replace",Replace[3,x_:> Rule[var_, x]]}
{"ReplaceAll",ReplaceAll[3, x_ :> Rule[var_, x]]}
{"ReplaceRepeated",ReplaceRepeated[{3},{x_Integer}:> Rule[var_, x]]}
{"With",With[{x=3},Rule[var_,x]]}
{"Module",Module[{x=3},Rule[var_,x]]}
(*not Block*)
(*{"Block",Block[{x=3},Rule[var_,x]]}*)
{"DynamicModule",ToString[DynamicModule[{x=3}, Rule[var_,x]],InputForm]}
(*The example below works for any "assignment function" (Set)*)
Clear[f]
{"Replacement by evaluation",Set[f[x_],RuleDelayed[var_,x]],f[3]}
(*not Function with Slots*)
(*Function[Rule[var_,#]][3]*)
{"FunctionNamedArg",Function[x,Rule[var_,x]][3]}

{Replace,varD_->3}
{ReplaceAll,varD_->3}
{ReplaceRepeated,varD_->3}
{With,varD_->3}
{Module,varD_->3}
{DynamicModule,DynamicModule[{x = 3}, varD_ -> 3, DynamicModuleValues :> {}]}
{Replacement by Evaluation, var_:>x, varD_:>3}
{FunctionNamedArg,varD_->3}


Understanding the examples

A general explanation of such examples can be found in the Q&A called "Enforcing correct variable bindings and avoiding renamings for conflicting variables in nested scoping constructs", in this answer. However I felt a bit more could be said about this.

The first list of examples basically lists all functions that could be considered "inner scoping constructs". The "inner scoping constructs" are searched for by "outer scoping constructs" in their bodies. The outer scoping constructs are listed in the second set of examples.

Replacement due to evaluation

Note that in the second list of examples there is an example with Set, labeled "Replacement by Evaluation". This example is different from the others, in that it is not Set here that is the function that looks for scoping constructs in its body. Rather, it appears that whenever the kernel evaluates an expression x and makes a replacement because x matches the pattern of a rule, the kernel emulates searching for scoping constructs in the RHS of this rule. The kernel already does a lot of this kind of bookkeeping, so maybe this is why it is not a big performance hit. In the example we use Set, but it appears that any definition made using "assignment functions" (SetDelayed, Set, TagSet, UpSet, TagSetDelayed, UpSetDelayed) will cause replacement of such variables. This replacement will happen for definitions corresponding to DownValues, UpValues as well as SubValues. It cannot happen for definitions that correspond to OwnValues as it is not possible to create an OwnValues with a pattern on the LHS of the (generated) rule.

Explanation of the question

I think interaction between inner and outer scoping constructs depends on the combination of the scoping constructs in a kind of independent manner. I.e. all the outer scoping constructs have the same strategy for to resolve a conflict between a local variable and the second argument of Rule. If this is true, all the interaction between inner and outer scoping constructs can be illustrated with only a few examples. I would consider the list to be exhaustive if all the cases where variable replacement happens can be predicted from the list, because all inner and outer scoping constructs are present.

Question

Are my examples exhaustive?

Related

StringReplace, ReplaceAll and Rule interact in a bizarre way (answer by Leonid)

-
How about TagSet and UpSet – Simon Woods May 27 '14 at 15:58
@SimonWoods you were right! – Jacob Akkerboom May 27 '14 at 16:15