这是特性还是bug
mathematica吧
全部回复
仅看楼主
level 10
Loydman 楼主
func1[f_]:=Module[{},
Table[{f,i},{i,1,3}]
];
func2[f_]:=Module[{i},
Table[{f,i},{i,1,3}]
];
func1[i+j]
func2[i+j]
按照文档的说法Table 会局部化变量,但是输入的 i 被视作索引变量了,这是特性吗
2025年07月30日 10点07分 1
level 1
我觉得应该是,“:=”的延迟作用导致会在代入f后Table才开始局部化变量,比如在运行func1(或者定义func1)前给i赋一个值看结果
2025年07月30日 13点07分 2
前排说一下,2楼与3楼对顶楼问题的解释均有误,具体请参考4楼及往后的讨论。
2025年08月18日 07点08分
level 9
Module creates a symbol with name xxx$nnn to represent a local variable with name xxx. The number nnn is the current value of $ModuleNumber.
因此第二个短代码中 Module[{i}, ...] 在局部 i 的全名是 i$ 数字, 和Table中的{i,1,3}的 i 不一样
2025年07月31日 12点07分 3
吧务
level 15
插一句,想要对这种重命名机制有更多了解可以参看SE帖子《Is the renaming mechanism of `With` flawed?》(编号 119403 ),想要有更多更多的了解的话,就把页面右侧Linked的部分也读一读。
2025年08月02日 09点08分 4
level 10
Loydman 楼主
我知道Module 会对变量创建 x$nn 这样的符号,我不理解的是为什么
func[f_] := Table[{f, i}, {i, 1, 3}]
func[i + j] 输出是 {{1 + j, 1}, {2 + j, 2}, {3 + j, 3}}
而不是 {{i + j, 1}, {i + j, 2}, {i + j, 3}}
这应该算比较反直觉吧[疑问]
2025年08月11日 11点08分 6
先说点别的:根据我的个人经验,不建议使用目前任何大语言模型来了解一些比较细节的Mathematica机制细节,表现都不是很好,一个原因可能是语料匮乏。包括DeepSeek R1, Gemini 2.5 Pro, Claude Sonnet 3.7。
2025年08月13日 10点08分
然后关于你这个问题,这是因为Table的局域化方式是Block,是动态作用域;而你前面实验的With,Module是都是词法作用域。这些在文档中都有明确说明。关于词法绑定与动态绑定的区别,你可参考https://www.emacswiki.org/emacs/DynamicBindingVsLexicalBinding,此问题比较成熟故应也可选择问大语言模型。
2025年08月13日 10点08分
Module所创建的x$nn符号与这个问题完全没有关系。这个创建在该Module被求值时才发生,但你Hold这个Module后同样有重命名的现象。另外,实际上可以构造只使用With的相似例子。具体看4楼提到的帖子吧。
2025年08月13日 11点08分
@asdasd1dsadsa 再插一句,Wolfram官方也在持续监测各大语言模型“根据英语说明生成 Wolfram 语言代码”的能力,网页名是《Wolfram LLM基准项目(Wolfram LLM Benchmarking Project)》,目前的测试结果,简单地说就是,都很拉。
2025年09月20日 12点09分
吧务
level 15
6楼楼中楼对此的解释是对的。此现象在自带文档“模块化和事物的命名 -> 纯函数和规则中的变量”一节也有介绍。为了便于理解,这里再多说几句。func2[i + j]中的i+j的i没有被替换,是因为Mathematica在这种情况下存在如下防止变量冲突的机制:
func2[i + j] // Trace
看见了吗,Module里的 i 多了个$,从外面传递进来的 i 则没受影响,注意此机制与 Module 生成临时变量的机制(即 i+$+数字 ,上图中也出现了)是完全不一样的。说到这里,聪明的读者可能会想到一个问题:如果我直接传个 i$ 变量进func2,会发生什么现象呢?“哈哈哈你想什么呢你难道以为Mathematica会被骗到吗肯定有相应的防冲突机制的嘛”……很遗憾,Mathematica还真会被骗:
func2[i$ + j]
(* {{1 + j, 1}, {2 + j, 2}, {3 + j, 3}} *)
更多相关讨论参看《Is the renaming mechanism of `With` flawed?》(编号 119403 )。
2025年08月18日 06点08分 7
吧务
level 15
最后,你在6楼贴了张sympy的代码图,似乎是在类比两个语言,对此,我得说:你这学习思路可能并不是很可取。虽然往大了说,sympy和Mathematica都有lisp的血统,但它们在具体实现上的差异其实很大,你观察到的sympy的行为,与Mathematica的行为大概有着本质的不同(我对sympy没啥研究,容我加个“大概”,如有错误欢迎指出),也会导致非常反直觉的行为。一个简单的例子:
from sympy import *
init_printing()
x= symbols('x')
expr=x**2
x=2
expr
expr.subs(x,2)
x= symbols('x')
expr.subs(x,2)
2025年08月18日 06点08分 8
1