Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лахов.doc
Скачиваний:
1
Добавлен:
15.04.2019
Размер:
380.42 Кб
Скачать

Рекурсивные макросы и продолжающиеся вычисления

Возникающая во время расширения макроса новое выражение может вновь содержать макровызов, возможно рекурсивный. Содержащийся в расширение макровызовы приводят на втором этапе вычислений к новым макровычислениям. С помощью рекурсивного макроса можно осуществить расширение, динамически зависящие от параметров, и продолжающееся макровычисление. Например, копирование верхнего уровня списка можно было бы определить следующим рекурсивным макросом:

_(defmacro copy-listq (x) ;аргументы не

(cond ((null x) nil) ; вычисляются

(t (list ‘cons ; вызов CONS в ; качестве расширения

(list ‘quote (car x))

(list ‘ copy- listq

(cdr x ))))))

COPY-LISTQ

_(copy-listq (A B C))

(A B C)

В результате первого расширения формируется выражение, содержащий новый макровызов:

(CONS (QUOTE A) (COPY- LISTQ (B C)))

Таким образом, расширение на втором этапе вычислений приводит к рекурсивному макровызову. Рекурсия заканчивается на вызове (COPY- LIST Q NIL), значением расширения которого является NIL.

Тестирование макросов

Макросы предусматривают собой эффективный инструмент которым, однако, тоже можно неверно воспользоваться. Из неправильно определенных макросов в результате расширения возникают неожиданные выражения, которые могут увести вычисления на неверный путь. Для тестирования макросов существует специальная функция, которая осуществляет лишь расширение макровызова:

(MACROEXPAND макровызов)

Ф

_(macroexpand ‘(copy- listq (a b c))

(CONS (QUOTE A) (COPY- LISTQ (B C)))

орма возвращает в качестве значения результат макрорасширения вызова, которое теперь можно изучить:

Обратная блокировка разрешает промежуточные вычисления

При раскрытии макроса обычно используется большое количество вложенных друг в друга вызовов функций CONS, CAR, CDR, LIST, APPEND и других. Поэтому при построении расширения можно легко ошибиться, а само макроопределение становиться менее прозрачным. Для облегчения написания макросов в ЛИСПе принят специальный механизм блокировки вычислений, который называют обратной блокировкой и который помечается в отличие от обычной блокировки (quote) наклонным в другую сторону (обратным) апострофом ” `“ (back quote).

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

Запятая дает возможность на время переключится в нормальное состояние вычислений. Пример:

_’(не_вычисляется (+3 4) ; обычный

(не_вычисляется (+3 4)) ; не отменяется

_ `(можно_ вычислить (+3 4)); действует

(можно_вычислить (+3 4)) ; как обычная блокировка

_ `(желательно_вычислить ,(+3 4)) ; , перед

(желательно_вычислить 7) ; выражением

; приводит к его вычислению

Лекция №8

СОПОСТАВЛЕНИЕ С ОБРАЗЦОМ

Сопоставление с образцом и распознавание образцов

Под сопоставлением с образцом (pattern matching) понимается процедура, при которой с известной структурой, или образцом (pattern, template), сопоставляется некоторая другая структура, или образ (pattern) с целью выявления единообразия или подобия структур или для выявления условий этого. Этот метод называют также распознаванием образов (pattern recognition),когда хотят подчеркнуть в процессе сторону идентификации образа, а не сопоставления с образцом.