Mathematica中的词汇和动态作用域:具有模块,具有和块的局部变量 [英] Lexical and dynamic scoping in Mathematica: Local variables with Module, With, and Block
问题描述
以下代码按预期返回14:
Block[{expr},
expr = 2 z;
f[z_] = expr;
f[7]]
但是,如果将Block
更改为Module
,则它将返回2*z
.
本地化除expr
以外的其他变量似乎也没有关系.
我以为我了解Mathematica中的Module,Block和With,但是在这个示例中我无法解释Module和Block在行为上的区别.
相关资源:
PS::感谢 Michael Pilat ,比尔·怀特(bill White)怪异的气味. 达沃拉克(Davorak)在此阐明并深入探讨了问题的实质: 为什么Mathematica会破坏模块中的常规作用域规则?
对此我也感到有些惊讶,但是我不认为这是一个错误.如果您仔细阅读参考页中的示例, 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
Function
是另一个类似于Module
的作用域构造,因此在Function
范围内将x
在内部重命名为x$
,类似于您在Trace
中发现的关于z
的内容. /p>
在定义f
的Module
中,Set
是另一个类似的作用域构造,因此,当在Module
内定义f
时,z
被重命名,但在Block
内定义时却没有重命名. >.遵循Module
文档中该示例的建议,您可以从函数的各个部分构建函数的RHS,以避免对嵌套作用域进行词汇重命名:
In[3]:= Clear[f, z]
In[4]:= Module[{expr},
expr = 2 z;
Set @@ {f[z_], expr};
f[7]]
Out[4]= 14
HTH!
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:
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
Function
is another scoping construct like Module
, so x
is renamed internally to x$
in the scope of the Function
, similar to what you discovered with Trace
about z
.
In your Module
defining f
, Set
is another such scoping construct, and therefore z
is renamed when f
is defined inside of a Module
, but not when it's inside a Block
. Following the advice of that example from the Module
documentation, you can build the RHS of your function from its parts to avoid the lexical renaming of the nested scope:
In[3]:= Clear[f, z]
In[4]:= Module[{expr},
expr = 2 z;
Set @@ {f[z_], expr};
f[7]]
Out[4]= 14
HTH!
这篇关于Mathematica中的词汇和动态作用域:具有模块,具有和块的局部变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!