Предотвращение оценки выражений Mathematica - PullRequest
15 голосов
/ 01 февраля 2011

В недавнем вопросе SO было дано три разных ответа, каждый из которых использовал свой метод предотвращения оценки выражения Equal[]. Они были

  1. Defer[]
  2. Unevaluated[]
  3. HoldForm[]

Иногда мне все еще трудно выбирать между этими вариантами (и, судя по ответам на перед упомянутым вопросом , выбор не всегда ясен и для других людей). Может ли кто-нибудь написать четкое изложение об использовании этих трех методов?


Есть еще три обертки Hold[], HoldPattern[], HoldComplete[], и различные Attributes для функций HoldAll, HoldFirst, HoldRest и числовые версии NHold*, которые также можно обсудить, если хотите!

Редактировать

Я только что заметил, что это в основном повтор старого вопроса (за который я уже проголосовал, просто забыл ...). Принятый ответ связан с этим докладом на конференции разработчиков Mathematica 1999 года, на которой не обсуждается Defer, поскольку он "Новое в 6". Defer более тесно связан с внешним интерфейсом, чем другие механизмы контроля оценки. Он используется для создания неоцененного вывода, которое будет оцениваться, если указано в выражении Input. Цитировать Центр документации :

Defer [expr] возвращает объект, который остается неизменным до явно предоставлено как Mathematica вход и оценивается с использованием Shift + Enter, оценка на месте и т. Д.

Ответы [ 2 ]

12 голосов
/ 01 февраля 2011

Не трогая Defer, так как я не очень много работал с ним и чувствую, что в любом конкретном случае его поведение может быть воспроизведено другими упомянутыми обертками, и обсуждается Hold вместо HoldForm (разница действительно в то, как они напечатаны), здесь - это ссылка на пост в математической группе, где я дал довольно подробное объяснение различий между Hold и Unevaluated, включая различия в использовании и в процессе оценки (мой второй и третий посты в частности).

Короче говоря, Hold используется для сохранения выражения, не оцененного между несколькими оценками (в течение неопределенного времени, пока оно нам не понадобится), является видимой оболочкой в ​​том смысле, что Depth[Hold[{1,2,3}]] не является такой же, как Depth[{1,2,3}] (это, конечно, следствие оценки), и, как правило, ничего особенного - просто обертка с атрибутом HoldAll, как и любой другой, за исключением того, что она является «официальной» оберткой для хранения и гораздо лучше интегрируется с остальными системы, поскольку многие системные функции используют или ожидают ее.

OTOH, Unevaluated[expr] используется для временного, только один раз, восполнения отсутствующего атрибута Hold * для функции, содержащей выражение expr. В то время как в результате получается поведение, которое потребовало бы, чтобы эта вмещающая функция содержала expr, как если бы она имела атрибут Hold* -, Unevaluated принадлежит аргументу и работает только один раз, для одной оценки, так как она удаляется в процессе. , Кроме того, поскольку он удаляется, он часто невидим для окружающих оболочек, в отличие от Hold. Наконец, это один из очень немногих «магических символов», наряду с Sequence и Evaluate - они глубоко подключены к системе и не могут быть легко скопированы или заблокированы, в отличие от Hold - в этом смысле Unevaluated более фундаментально.

HoldComplete используется, когда требуется предотвратить определенные этапы процесса оценки, что Hold не мешает. Это включает последовательности сплайсинга, например:

In[25]:= {Hold[Sequence[1, 2]], HoldComplete[Sequence[1, 2]]}

Out[25]= {Hold[1, 2], HoldComplete[Sequence[1, 2]]},

поиск UpValues, например

In[26]:= 
ClearAll[f];
f /: Hold[f[x_]] := f[x];
f[x_] := x^2;

In[29]:= {Hold[f[5]], HoldComplete[f[5]]},

Out[29]= {25, HoldComplete[f[5]]}

и иммунитет к Evaluate:

In[33]:= 
ClearAll[f];
f[x_] := x^2;

In[35]:= {Hold[Evaluate[f[5]]], HoldComplete[Evaluate[f[5]]]}

Out[35]= {Hold[25], HoldComplete[Evaluate[f[5]]]}   

Другими словами, он используется, когда вы хотите предотвратить какую-либо оценку выражения внутри. Как и Hold, HoldComplete не является чем-то особенным в том смысле, что это просто «официальная» оболочка с атрибутом HoldAllComplete, и вы можете создать свою собственную, которая будет вести себя аналогично.

Наконец, HoldPattern - это обычная (обычная) голова с атрибутом HoldAll для целей оценки, но ее магия проявляется в сопоставлении с образцом: она невидима для сопоставителя с образцом и является очень важным компонентом языка, так как он позволяет шаблону сопоставления с процессом оценки. Всякий раз, когда существует опасность, что шаблон в каком-либо правиле может быть оценен, можно использовать HoldPattern, чтобы гарантировать, что этого не произойдет, в то время как шаблон остается таким же для сопоставителя шаблонов. Здесь я бы хотел подчеркнуть, что это единственная цель. Часто люди используют его также в качестве механизма экранирования для сопоставления с образцом, где вместо него следует использовать Verbatim. Это работает, но концептуально неверно.

Один очень хороший отчет о процессе оценки и обо всех этих вещах - книга Дэвида Вагнера, Мощное программирование с Mathematica - ядром , которое было написано в 1996 году для версии 3, но большинство, если не все, обсуждение там остается в силе сегодня. Увы, он распечатан, но вам, возможно, повезет на Amazon (как я это сделал несколько лет назад).

5 голосов
/ 01 февраля 2011

Ответ Леонида Шифрина довольно хороший, но я хотел бы затронуть вопрос Defer, который действительно полезен только для одной вещи. В некоторых случаях приятно иметь возможность напрямую создавать выражения, которые не будут оцениваться, но которые пользователь сможет легко редактировать; основным примером такого поведения являются палитры кнопок, которые можно использовать для вставки выражений или шаблонов выражений в ячейки ввода, которые затем пользователь может редактировать по мере необходимости. Это не единственный способ сделать это, и для некоторых более сложных приложений вам нужно попасть в волосатый мир MakeBoxes, но для основ Defer будет хорошо работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...