Ответ 1
OwnValues[a] = {HoldPattern[a] -> 3}; OwnValues[a]
дает {HoldPattern[a] :> 3}
вместо {HoldPattern[a] -> 3}
, но Definition[a]
показывает, чего можно ожидать. Вероятно, это определение хранится внутри в форме Rule
, но преобразуется в RuleDelayed
на OwnValues
для подавления оценки r.h.s определения. Эта гипотеза противоречит моему первоначальному пониманию того, что нет разницы между значениями, присвоенными Set
и SetDelayed
. Вероятно, такие определения хранятся в разных формах: Rule
и RuleDelayed
соответственно, но эквивалентны с точки зрения оценщика.
Интересно посмотреть, как MemoryInUse[]
зависит от вида определения.
В следующем эксперименте я использовал ядро Mathematica 5.2 в интерактивном сеансе без FrontEnd. С ядрами Mathematica 6 и 7 будут получены разные результаты. Одна из причин этого заключается в том, что в этих версиях Set
по умолчанию перегружен.
Прежде всего, я оцениваю $HistoryLength=0;
за то, что DownValues
для переменных In
и Out
не влияет на мои результаты. Но кажется, что даже когда $HistoryLength
установлено в 0, значение In[$Line]
для строки current сохраняется и удаляется после ввода нового ввода. Вероятно, это причина, по которой результат первой оценки MemoryInUse[]
всегда отличается от второй.
Вот что я получил:
Mathematica 5.2 для студентов: версия Microsoft Windows
Copyright 1988-2005 Wolfram Research, Inc.
- инициализирована графическая карта терминала -
В [1]: = $HistoryLength = 0;
В [2]: = MemoryInUse []
Out [2] = 1986704
В [3]: = MemoryInUse []
Out [3] = 1986760
В [4]: = MemoryInUse []
Out [4] = 1986760
В [5]: = a = 2;
В [6]: = MemoryInUse []
Out [6] = 1986848
В [7]: = MemoryInUse []
Out [7] = 1986824
В [8]: = MemoryInUse []
Out [8] = 1986824
В [9]: = a: = 2;
В [10]: = MemoryInUse []
Out [10] = 1986976
В [11]: = MemoryInUse []
Out [11] = 1986952
В [12]: = MemoryInUse []
Out [12] = 1986952
В [13]: = a = 2;
В [14]: = MemoryInUse []
Out [14] = 1986848
В [15]: = MemoryInUse []
Вывод [15] = 1986824
В [16]: = MemoryInUse []
Out [16] = 1986824
Можно видеть, что определение a=2;
увеличивает MemoryInUse[]
на 1986824-1986760 = 64 байта. Замена его на определение a:=2;
увеличивает MemoryInUse[]
на 1986952-1986824 = 128 байт. И заменив последнее определение на прежнее, возвращается MemoryInUse[]
до 1986824 байта. Это означает, что отложенные определения требуют 128 байтов больше, чем непосредственные определения.
Конечно, этот эксперимент не подтверждает мою гипотезу.