Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лисп.docx
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
1.66 Mб
Скачать

24.Макросы.

Часто бывает полезно не выписывать вычисляемое выражение вручную, а сформировать его с помощью программы. Эта идея автоматического динамического программирования особенно хорошо реализуется в Лиспе, поскольку программа в этом языке также представляется в виде списка. При этом вычисление такого выражения или его части при необходимости можно предотвратить блокировкой (QUOTE), например, с целью преобразования выражения. Для вычисления же сформированного выражения программист всегда может вызвать интерпретатор (EVAL).

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

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

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

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

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

(DEFMACRO имя лямбда-список тело)

Вызов макроса совпадает по форме с вызовом функции, но его вычисление отличается от вычисления вызова функции.

1)в макросе не вычисляются аргументы. Тело макроса вычисляется с аргументами в том виде, как они записаны

2)связано со способом вычисления тела макроса. Вычисление вызова макроса состоит из двух последовательных этапов. На первом этапе осуществляется вычисление тела определения с аргументами из вызова таким же образом, как и для функции.. На втором этапе вычисляется полученная из вызова раскрытая форма, значение которой возвращается в качестве значения всего макровызова.

Макрос - это форма, которая во время вычисления заменяется на новую, обычно более сложную форму, которая затем вычисляется обычным образом.

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]