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)
Comments
Post a Comment