I want to use a replacement rule to change log[var]
into var
inside a function. A minimal example follows. In one case it works; in the other it doesn't. Could someone explain the difference and how to fix in the second case?
unks = {log[n]};
foo1[x_] := Table[(unk /. log[var_] -> var) -> 5, {unk, unks}];
foo2[x_] := Table[(unk /. log[var_] -> var) -> x, {unk, unks}];
foo1[5]
(* {n -> 5} -- good *)
foo2[5]
(* {var -> 5} -- bad *)
Applying Trace
shows that the bad foo2
contains log[var$_] -> var
, which seems like the source of the problem. What's that $
doing there?
x_
is causing the lexical scoping mechanism to come into play but theHoldFirst
onTable
is breaking that. Check out this:foo3[x_] := With[{reps={log[var_] :> var}}, Table[(unk/.reps)->x, {unk, unks}]]
$\endgroup$Replace[..., rule, {1}]
onunks
first I imagine. Or if you need it deeper just to the/.
there first or do aReplace[..., rule, {1, Infinity}]
or something along those lines. $\endgroup${log[n] -> some stuff, log[m] -> some other stuff}
that I need to transform to{n -> some (slightly different) stuff, m -> some other (slightly different) stuff}
. $\endgroup$Thread[Replace[Keys[#], log[n_]:>n, {1}]->Values[#]]&
might be the least likely to have side effects. Alternately create your replacement rules first withDispatch
to get most of the benefit of vectorizing the call. $\endgroup$HoldFirst
ofTable
doesn't seem to be the issue:1 /. x_ -> ((var_ -> var) -> x)
returns(var$_ -> var) -> 1
, which is already broken. From a few quick tests, it seems that all the rules in the example are needed for it to return strange results. $\endgroup$