The following code returns 14 as you’d expect:
Block[{expr},
expr = 2 z;
f[z_] = expr;
f[7]]
But if you change that Block to a Module then it returns 2*z.
It seems to not matter what other variables besides expr you localize.
I thought I understood Module, Block, and With in Mathematica but I can’t explain the difference in behavior between Module and Block in this example.
Related resources:
- Tutorial on Modularity and the Naming of Things from the Mathematica documentation
- Excerpt from a book by Paul R. Wellin, Richard J. Gaylord, and Samuel N. Kamin
- Explanation from Dave Withoff on the Mathematica newsgroup
PS: Thanks to Michael Pilat, Davorak, and Bill White for following the scent-trail on this weirdness.
Davorak clarifies and gets to the heart of the issue here:
Why would Mathematica break normal scoping rules in Module?
I too was a bit surprised by this, but I don’t think it’s a bug. If you look deep in the examples in the reference page for
Module, under the section labeled Possible Issues, there’s a little note that says “Variables are renamed in nested scopes” and gives the following example:Functionis another scoping construct likeModule, soxis renamed internally tox$in the scope of theFunction, similar to what you discovered withTraceaboutz.In your
Moduledefiningf,Setis another such scoping construct, and thereforezis renamed whenfis defined inside of aModule, but not when it’s inside aBlock. Following the advice of that example from theModuledocumentation, you can build the RHS of your function from its parts to avoid the lexical renaming of the nested scope:HTH!