Mathematica中的词法和动态范围:具有Module,With和Block的局部变量

dre*_*ves 7 variables scope localization wolfram-mathematica module

以下代码按预期返回14:

Block[{expr},
  expr = 2 z;
  f[z_] = expr;
  f[7]]
Run Code Online (Sandbox Code Playgroud)

但是,如果你改变BlockModule则返回2*z.除了expr你本地化之外,其他变量似乎并不重要.我以为我理解Mathematica中的Module,Block和With但是我无法解释这个例子中Module和Block之间的行为差​​异.

相关资源:

PS:感谢迈克尔·皮拉特, 达沃拉克比尔·怀特追随这种奇怪的气味.Davorak澄清并深入探讨了问题的核心: 为什么Mathematica会破坏模块中的正常范围规则?

Mic*_*lat 6

我也有点惊讶,但我不认为这是一个错误.如果您仔细查看参考页面Module中的示例,在标记为可能问题的部分下,会有一个小注释"在嵌套作用域中重命名变量",并给出以下示例:

In[1]:= Module[{e = Expand[(1 + x)^5]}, Function[x, e]]

Out[1]= Function[x$, e$1194]

In[2]:= %[10]

Out[2]= 1 + 5 x + 10 x^2 + 10 x^3 + 5 x^4 + x^5 
Run Code Online (Sandbox Code Playgroud)

Function是另一个范围构造Module,因此x在内部重命名为x$范围Function,类似于您发现的Trace内容z.

在你的Module定义中f,Set是另一个这样的范围构造,因此在a内部定义z时重命名,而不是在fa里面定义.根据文档中该示例的建议,您可以从其各个部分构建函数的RHS,以避免嵌套作用域的词法重命名:ModuleBlockModule

In[3]:= Clear[f, z]

In[4]:= Module[{expr},
  expr = 2 z;
  Set @@ {f[z_], expr};
  f[7]]

Out[4]= 14
Run Code Online (Sandbox Code Playgroud)

HTH!