问题
One may set a Default value for the arguments of a function:
Default[f] = 5;
And then use:
f[a_, b_.] := {a, b}
f[1, 2]
f[1]
{1, 2}
{1, 5}
This creates the following Values:
DefaultValues[f]
DownValues[f]
{HoldPattern[Default[f]] :> 5}
{HoldPattern[f[a_, b_.]] :> {a, b}}
From this one might think that the value 5 is not fixed in the definition of f, but addresses the DefaultValues assignment. However, if we change the DefaultValues, either directly or using:
Default[f] = 9;
DefaultValues[f]
{HoldPattern[Default[f]] :> 9}
and use f again:
f[1]
{1, 5}
we see that the new value is not used.
Therefore, my questions are:
Why does the default value used by
f[a_, b_.] := {a, b}not change withDefaultValues?Where is the real default value (
5) stored, since it does not appear in eitherDownValuesorDefaultValues?
回答1:
Not an answer, but:
Using the behaviour that the original default is kept until the function is redefined suggests a quick work-around:
Define a global variable for the Default before any other definitions are made.
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
This also works for Optional
In[1]:= g[a_:$g] := a
In[2]:= g[]
Out[2]= $g
In[3]:= $g=1; g[]
Out[4]= 1
回答2:
From the documentation,
The necessary values for
Default[f]must always be defined before_.is used as an argument off.
Redefining f after setting Default[f] = 9; uses the new default value. So my guess is it is defined internally the first time, f is defined, and doesn't change even if DefaultValue@f stores the new value.
回答3:
I have found that this behavior in the case of local rules is due to specifics of internals of RuleDelayed.
Compare:
In[1]:= Default[f] = 5;
replaceAll[f[1],
f[a_, b_.] :> Unevaluated@{a, b}] /. (Default[f] = 9; replaceAll) ->
ReplaceAll
Default[f] = 5;
Block[{RuleDelayed},
replaceAll[f[1],
f[a_, b_.] :> Unevaluated@{a, b}] /. (Default[f] = 9;
replaceAll) -> ReplaceAll]
Out[2]= {1, 5}
Out[4]= Unevaluated[{1, 9}]
One can see that Blocking RuleDelayed makes local rules to behave as one could expect.
来源:https://stackoverflow.com/questions/6337753/why-does-default-behave-like-this