Вопрос о определении и значениях символов

Definition "знает" способ определения значения для символа: с помощью Set или SetDelayed. Но как? Насколько я понимаю, после того, как значение для символа было назначено, для оценщика нет никакой разницы, как это было назначено: с помощью Set или SetDelayed. Это можно проиллюстрировать функцией OwnValues, которая всегда возвращает определения с Head RuleDelayed. Как Definiton получает эту информацию?

In[1]:= a=5;b:=5;
Definition[a]
Definition[b]
OwnValues[a]

Out[2]= a=5
Out[3]= b:=5
Out[4]= {HoldPattern[a]:>5}

Ответы

Ответ 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 байтов больше, чем непосредственные определения.

Конечно, этот эксперимент не подтверждает мою гипотезу.

Ответ 2

Доступ к полному определению для символа можно получить с помощью недокументированных символов "новый-в-8" Language`ExtendedDefinition и Language`ExtendedFullDefinition. Цитирование Александр Распутинов:

"Если кому-то интересно, Language`ExtendedDefinition и Language`ExtendedFullDefinition аналогичны Definition и FullDefinition, но фиксируют определение символа таким образом, что оно может быть воспроизведено в другом ядре. Например, defs = Language`ExtendedFullDefinition[sym] возвращает объект Language`DefinitionList. Синтаксис, используемый для восстановления определения, является очень нерегулярным: Language`ExtendedFullDefinition[] = defs, где defs является Language`DefinitionList. Обратите внимание, что Language`ExtendedFullDefinition принимает параметр ExcludedContexts, тогда как Language`ExtendedDefinition делает не".

Ответ 3

Information вызывает Definition, а трассировка на Definition (или FullDefinition) ничего не показывает. Я должен предположить, что это низкоуровневая функция, которая обращается к данным вне таблиц *Values. Возможно, он сохраняет копию исходных выражений определения, поскольку они были проанализированы в то время.