为什么Default表现得像这样?

Mr.*_*ard 14 wolfram-mathematica

可以Default为函数的参数设置一个值:

Default[f] = 5;
Run Code Online (Sandbox Code Playgroud)

然后使用:

f[a_, b_.] := {a, b}

f[1, 2]
f[1]
Run Code Online (Sandbox Code Playgroud)
   {1, 2}
   {1, 5}

这将创建以下值:

DefaultValues[f]
DownValues[f]
Run Code Online (Sandbox Code Playgroud)
   {HoldPattern[Default[f]] :> 5}
   {HoldPattern[f[a_, b_.]] :> {a, b}}

从这个可能会认为该值5不是在定义中固定f,而是解决了DefaultValues赋值.但是,如果我们DefaultValues直接或使用以下方式更改:

Default[f] = 9;

DefaultValues[f]
Run Code Online (Sandbox Code Playgroud)
   {HoldPattern[Default[f]] :> 9}

f再次使用:

f[1]
Run Code Online (Sandbox Code Playgroud)
   {1, 5}

我们看到没有使用新值.

因此,我的问题是:

  • 为什么使用的默认值f[a_, b_.] := {a, b}不会改变DefaultValues

  • 哪里是真正的默认值(5)存储,因为它没有在任何出现DownValuesDefaultValues

Sim*_*mon 10

不是答案,但是:
使用保留原始默认值的行为,直到重新定义函数为止,建议快速解决:

Default在进行任何其他定义之前定义全局变量.

In[1]:= Default[f]:=$f
In[2]:= f[a_.]:=a

In[3]:= f[]
Out[3]= $f

In[4]:= $f=5; f[]
Out[5]= 5
In[6]:= $f=6; f[]
Out[7]= 6
In[8]:= $f=.; f[]
Out[9]= $f
Run Code Online (Sandbox Code Playgroud)

这也适用于 Optional

In[1]:= g[a_:$g] := a

In[2]:= g[]
Out[2]= $g

In[3]:= $g=1; g[]
Out[4]= 1
Run Code Online (Sandbox Code Playgroud)


abc*_*bcd 8

文档中,

Default[f]必须始终定义必要的值才能_.用作参数f.

f设置后重新定义Default[f] = 9;使用新的默认值.所以我的猜测是它是第一次在内部f定义,定义,即使DefaultValue@f存储新值也不会改变.

  • 但它在哪里存储?旧的默认值似乎没有出现在任何`*Values`中...... (3认同)
  • @yoda这个问题似乎与*global*规则有关.你可以在本地用`f`试试你的例子:`f [1] /.f [a_,b_.]:> {a,b}`(首先删除了它的全局def),并看到**对`Default [f]`的变化敏感.我的猜测是全局规则(定义)在定义时可能会经历一些内部优化,这需要定义时的"默认"值.定义完成后,它会得到优化并对`Default [f]`的变化不敏感,除非我们有一个间接级别,如@ Simon的答案. (3认同)
  • @ Mr.W:对不起,但这意味着更多可能的解释,而不是具体的答案(以防你在文档中错过了这一部分).此外,由于这是记录的行为,我没有看到第一个问题的意义(它是什么).但第二个,我真的不知道,我没有试图回答它.我想我应该明白我的意图. (2认同)
  • 对不起,如果出现粗鲁的话.我知道其他人(除了主持人)看不到我的选票,但不知怎的,我觉得我需要解释为什么我没有投票支持这一点,我担心这听起来有点贬义.至于"默认",对我来说,答案中的引用并不排除以后可以更改"默认[f]"的可能性,并且该更改将影响以前的使用.(对'DownValues`的检查表明这**应该起作用.)相反,它告诉我在没有定义的'Default`的情况下使用`_.可能或将在赋值期间注册为错误. (2认同)
  • @Alexey我不清楚这是发生在一般评估中还是只与"Set"和"SetDelayed"的评估以及分配过程有关.因为我怀疑后者(否则不清楚为什么在`f [1]/.f [a_,b_.]:> {a,b}中的局部规则中对可选模式的评估不会导致相同的"默认`不敏感行为",由于`Set`和`SetDelayed`产生全局规则,我称之为"全局规则效应". (2认同)