2
$\begingroup$

I've run into a strange anomaly with Replace when it is performed inside the first argument of RuleDelayed within a function that includes one of its parameters as the second argument to the same RuleDelayed. Obscure, I know, and I can work around it, I'm sure, but it has me scratching my head.

Replace is finding a match, but is unable to utilize the pattern labels I provided on the RHS of the replacement expression. The problem goes away if I only replace at e.g. level {0} or if I don't use the function argument in the RuleDelayed... Any ideas?

See below:

ClearAll[ReplaceProblem]

ReplaceProblem[a_] := RuleDelayed[
  Replace[NotEvenUsing@AnyParameters, 
   f_[x : Except[_Pattern]] :> f[x]],
  a]

ReplaceProblemGone[a_] := RuleDelayed[
  Replace[NotEvenUsing@AnyParameters, 
   f_[x : Except[_Pattern]] :> f[x]],
  abc]

Column[#, Frame -> All] &@Trace@
  ReplaceProblem[a]

Column[#, Frame -> All] &@Trace@
  ReplaceProblemGone[a]

Output (bad version):

ReplaceProblem[a]
Replace[NotEvenUsing[AnyParameters],f$_[x$:Except[_Pattern]]:>f[x]]:>a
{{f$_[x$:Except[_Pattern]]:>f[x],f$_[x$:Except[_Pattern]]:>f[x]},Replace[NotEvenUsing[AnyParameters],f$_[x$:Except[_Pattern]]:>f[x]],f[x]}
f[x]:>a
f[x]:>a

Output (good version):

ReplaceProblemGone[a]
Replace[NotEvenUsing[AnyParameters],f_[x:Except[_Pattern]]:>f[x]]:>abc
{{f_[x:Except[_Pattern]]:>f[x],f_[x:Except[_Pattern]]:>f[x]},Replace[NotEvenUsing[AnyParameters],f_[x:Except[_Pattern]]:>f[x]],NotEvenUsing[AnyParameters]}
NotEvenUsing[AnyParameters]:>abc
NotEvenUsing[AnyParameters]:>abc

I seemed to have confused the automatic scoping rules somehow...? Where did I break some rule???

$\endgroup$
4
  • 3
    $\begingroup$ This is another one of the issues with lexical scoping emulation in WL. The most recent one: 1. Check these Q/As for explanations: 2, 3, 4, in that order. $\endgroup$ Feb 2, 2021 at 23:04
  • $\begingroup$ And after that, you will understand why either of these two modifications of your code will fix it: ClearAll[ReplaceProblem]; ReplaceProblem[a_] := RuleDelayed @@ Hold[Replace[NotEvenUsing@AnyParameters, f_[x : Except[_Pattern]] :> f[x]], a], or ClearAll[ReplaceProblem]; ReplaceProblem[a_] := With[{rd = RuleDelayed}, rd[Replace[NotEvenUsing@AnyParameters, f_[x : Except[_Pattern]] :> f[x]], a]]. $\endgroup$ Feb 2, 2021 at 23:06
  • $\begingroup$ A response from the master himself! Thanks @LeonidShifrin, reading through your linked material. $\endgroup$
    – Sean
    Feb 5, 2021 at 13:05
  • $\begingroup$ Glad to help. I hope those links were useful. $\endgroup$ Feb 5, 2021 at 17:49

0

Browse other questions tagged or ask your own question.