Подтвердить что ты не робот

Почему Default ведет себя так?

Можно задать значение Default для аргументов функции:

Default[f] = 5;

И затем используйте:

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

f[1, 2]
f[1]
   {1, 2}
   {1, 5}

Это создает следующие значения:

DefaultValues[f]
DownValues[f]
   {HoldPattern[Default[f]] :> 5}
   {HoldPattern[f[a_, b_.]] :> {a, b}}

Из этого можно подумать, что значение 5 не определено в определении f, но адресует назначение DefaultValues. Однако, если мы изменим DefaultValues, либо напрямую, либо используя:

Default[f] = 9;

DefaultValues[f]
   {HoldPattern[Default[f]] :> 9}

и снова используйте f:

f[1]
   {1, 5}

мы видим, что новое значение не используется.

Поэтому мои вопросы:

  • Почему значение по умолчанию, используемое f[a_, b_.] := {a, b}, не изменяется с помощью DefaultValues?

  • Где хранится реальное значение по умолчанию (5), поскольку оно не отображается ни в DownValues, либо DefaultValues?

4b9b3361

Ответ 1

Не ответ, но:
Используя поведение, сохраненное по умолчанию, до тех пор, пока функция не будет переопределена, вы можете быстро обходиться:

Определите глобальную переменную для 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

Это также работает для Optional

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

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

In[3]:= $g=1; g[]
Out[4]= 1

Ответ 2

Из документации,

Необходимые значения для Default[f] всегда должны быть определены до того, как _. будет использоваться как аргумент f.

Переопределение f после установки Default[f] = 9; использует новое значение по умолчанию. Поэтому я предполагаю, что он определяется внутренне в первый раз, f определен и не изменяется, даже если [email protected] сохраняет новое значение.

Ответ 3

Я обнаружил, что это поведение в случае локальных правил обусловлено спецификацией внутренних элементов RuleDelayed.

Для сравнения:

In[1]:= Default[f] = 5;
replaceAll[f[1], 
  f[a_, b_.] :> [email protected]{a, b}] /. (Default[f] = 9; replaceAll) ->
   ReplaceAll

Default[f] = 5;
Block[{RuleDelayed}, 
 replaceAll[f[1], 
   f[a_, b_.] :> [email protected]{a, b}] /. (Default[f] = 9; 
    replaceAll) -> ReplaceAll]

Out[2]= {1, 5}

Out[4]= Unevaluated[{1, 9}]

Можно видеть, что Block ing RuleDelayed приводит к тому, что локальные правила ведут себя так, как можно было бы ожидать.