I understand why $ happens here:

foo[a_] := (x_ :> a x)

x$_ :> 1 x$

For future readers, see: Enforcing correct variable bindings and avoiding renamings for conflicting variables in nested scoping constructs

But I don't understand this one:

foo[a_] := (x_ :> a x) -> a

(x$_ :> 1 x) -> 1

Only one x is renamed. Should I expect this or is this a bug?

Somehow I feel this one is related:

Bug with iterated With: Referring to function arguments invalidates previous definitions

p.s. here is a oneliner:

Key["a"] /. Key[name_] :> ((whatever_ :> whatever) -> name)
(whatever$_ :> whatever) -> "a"

The real use case is something along

    Key["a"] /. Key[name_] :> (( 1 /. whatever_ :> whatever) -> name)

Where I'd expect 1 -> "a" instead of whatever -> "a"

  • $\begingroup$ This is much more related to this and this questions, where I tried to explain the mechanism behind this (I think this behavior can be viewed as a bug, or borderline bug). Perhaps this can be categorized as a dupe of one of those. $\endgroup$ – Leonid Shifrin Aug 28 '18 at 22:51
  • $\begingroup$ @LeonidShifrin I agree. Sadly StrictLexicalScoping is not an option if I write code for others. I don't want to change system settings without confirmation that it is safe. $\endgroup$ – Kuba Aug 29 '18 at 10:56
  • 1
    $\begingroup$ Makes sense, alas. AFAIK, this has not been set to True by default, because WA was not building properly with this. Apparently, current (arguably buggy) behavior has been used and relied upon. $\endgroup$ – Leonid Shifrin Aug 30 '18 at 12:33

Browse other questions tagged or ask your own question.