3
$\begingroup$

I've come across some weirdness in ReplaceAll. Replacement works fine outside of a module, but inside the module some replacements don't occur where one might expect them to.

In[2]:= f = ListInterpolation[{1, 2, 3, 5, 8, 5}]

Out[2]= InterpolatingFunction[{{1, 6}}, <>]

In[3]:= g = D[f[x], x]

Out[3]= InterpolatingFunction[{{1, 6}}, <>][x]

In[4]:= h[u_] := Module[{x, z}, x + u /. {x -> z}]

In[5]:= h[g]

Out[5]= z$6446 + InterpolatingFunction[{{1, 6}}, <>][x]

In[6]:= x + g /. x -> z

Out[6]= z + InterpolatingFunction[{{1, 6}}, <>][z]

Note that outside of the module x gets replaced by z in both places where it occurs in the expression. But inside the module the parameter x of the InterpolationFunction does not get replaced with z.

Can anybody explain this to me please?

$\endgroup$
  • 2
    $\begingroup$ This is the full story: avoiding renamings for conflicting variables. This is related: Package functions and symbolic calculations $\endgroup$ – Kuba Feb 25 at 10:03
  • $\begingroup$ Many thanks for your clear explanation Nasser. I have rewritten the code to avoid having to pass x as a parameter of the InterpolationFunction and hence no need to use ReplaceAll. $\endgroup$ – SkyCat Feb 25 at 15:32
  • $\begingroup$ If you really want to understand why this happens, look e.g. here and here. But this is not very simple, one needs to have some understanding of the core language to get the most out of those discussions. You have run into an edge case, in a way. $\endgroup$ – Leonid Shifrin Feb 25 at 19:33
1
$\begingroup$

That is because local x is the not same as the global x. Different context.

Best thing to handle these things, is to pass to the module the symbols of interest along with the expression itself. Like this

 h[u_, x_, z_] := Module[{}, x + u /. {x -> z}]
 h[g, x, z]

Gives

Mathematica graphics

Which is the same as

 x + g /. x -> z

Mathematica graphics

Another way is

h[u_] := With[{x = x, z = z}, x + u /. {x -> z}]
h[g]

Mathematica graphics

But I prefer the first method. Pass the global symbols to the module. This is what many functions in Mathematica do. For example in DSolve[y'[x]==x,y[x],x] the user is passing the global symbols y and x down to the module DSolve. The reason is the same.

When a module returns an expression using its own local symbols in it, Mathematica adds these $nnnn to the symbol name. So by passing the symbol name down to the module, you avoid this.

| improve this answer | |
$\endgroup$
  • 1
    $\begingroup$ I don't think this is the correct explanation. The problem of the OP seems to be related to similar problems discussed earlier on this site (I referred to those in comment to the question), and is a much more subtle by nature. $\endgroup$ – Leonid Shifrin Feb 25 at 19:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.