Mathematica中的词汇和动态作用域:具有模块,具有和块的局部变量

编程入门 行业动态 更新时间:2024-10-08 18:36:09
本文介绍了Mathematica中的词汇和动态作用域:具有模块,具有和块的局部变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

以下代码按预期返回14:

Block[{expr}, expr = 2 z; f[z_] = expr; f[7]]

但是,如果将Block更改为Module,则它将返回2*z. 本地化除expr以外的其他变量似乎也没有关系. 我以为我了解Mathematica中的Module,Block和With,但是在这个示例中我无法解释Module和Block在行为上的区别.

相关资源:

  • Mathematica文档中的有关模块化和事物命名的指南
  • 摘录自书
  • Mathematica新闻组上Dave Withoff的解释

PS::感谢 Michael Pilat ,达沃拉克(aavo)和比尔·怀特(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中的词汇和动态作用域:具有模块,具有和块的局部变量

本文发布于:2023-11-25 20:59:51,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1631324.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:变量   局部   词汇   模块   作用

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!