2012-05-31 2 views
1

Всюду, состояние гуру: «Динамическое определение может быть настолько мощным по сравнению с лексическим охватом.», но до сих пор я никогда не видел опрятного примера, который меня убедил.Lisp динамический обзор: мощный короткий пример, рассуждающий?

+0

Разве это не должно быть в разделе чата? – ilomambo

+0

Посмотрите на emacs. Это также иногда предпочтительнее глобальных переменных. – Marcin

ответ

3

Мой любимый пример хорошо объясняется в работе Emacs: http://www.gnu.org/software/emacs/emacs-paper.html#SEC17

Динамическая сфера полезна. Рассмотрим функцию Edit Picture, которая используется для изменения некоторых команд редактирования немного, временно, так что они более удобны для редактирования текста, который упорядочен в виде двумерных изображений . Например, печатные символы изменены , чтобы заменить существующий текст вместо того, чтобы сдвигать его вправо. Редактировать Изображение работает путем динамического связывания значений переменных параметров , а затем вызывает редактор как подпрограмму. Редактор команда «exit» вызывает возврат в подпрограмму «Редактировать изображение», которая немедленно возвращается к внешнему вызову редактора. В процессе привязки динамической переменной не применяются.

Динамическое связывание особенно полезно для элементов команды Таблица рассылки. Например, команда RMAIL для составления ответа на сообщение временно определяет символ Control - Meta - Y до , вставьте текст исходного сообщения в ответ. Функция , которая реализует эту команду, всегда определяется, но Control-Meta-Y не вызывает эту функцию, кроме как при редактировании ответа. Команда ответа выполняет это путем динамической привязки таблицы отправки записи для Control - Meta - Y, а затем вызывает редактор как подпрограмму . Когда возвращается рекурсивный вызов редактора, текст , отредактированный пользователем, отправляется в виде ответа.

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

3

Я много лет назад привык к динамическому охвату при использовании языка Clipper5 (расширенная реализация исходного языка программирования DBIII).

Если правильно использовать динамическую область, это очень полезно, потому что позволяет передавать параметры по цепочке вызовов, не задавая им промежуточные функции. Это упрощает добавление, например, новых параметров только в требуемом месте (то есть, где этот параметр возникает и где используется параметр.

Предположим, у вас есть «близкий порядок», который вызывает «документация на печать» «который вызывает« print-invoice », который вызывает« print-invoice-row ». Если вам нужно добавить новый параметр, который повлияет на то, как строки счета будут распечатаны, вы можете просто добавить пользовательский параметр на верхнем уровне" close-order ", установите динамическую переменную с этим значением и обработайте только значение в строке« print-invoice-row ».

Цепочка интерфейса функций останется« чистой »от этого параметра, перечисляя только фундаментальные данные,

Это похоже на использование глобальной переменной, но она «выполнена правильно», потому что после вызова она не останется «грязной», а в большинстве реализаций, поддерживающих потоки, она может даже использоваться из нескольких потоков без проблем (каждый поток будет иметь его собственные значения).

Я нашел в прошлом возможность использовать этот подход для значений «конфигурации» очень полезно. Однако вы должны обратить внимание, чтобы избежать нежелательного имени.

Другим примером хорошего использования является *standard-output* в Common Lisp, то есть значение, которое в противном случае вам нужно хранить в глобальном (например, на языке C) или для которого другая, очевидно, непрактичная альтернатива - передать ее каждой функции это потенциально нуждается в нем (либо использовать его напрямую, либо вызвать функцию, которая ему в этом нуждается).

Выполнение *standard-output* Динамическая переменная позволяет программе Common Lisp избегать ссылки на нее повсюду, сохраняя при этом возможность перенаправления стандартного вывода на что-то другое, если это необходимо (и гораздо более чистым способом, чем на C).

Смежные вопросы