
- •Декларативные и императивные языки.
- •Стандартизация языков программирования
- •Типы данных
- •Структуры данных
- •Парадигма программирования
- •Способы реализации языков
- •Языки функционального программирования
- •Создание универсального функционального языка.
- •3. Символьная обработка и искусственный интеллект.
- •4. Применение искусственного интеллекта.
- •5. Основы языка лисп (6 – 15 вопросы)
- •6. Символы и списки
- •7. Понятие функции
- •8. Базовые функции Лиспа.
- •9. Имя и значение символа Лиспа.
- •10. Определение функций Лиспа.
- •11. Передача параметров в область их действия Лиспа.
- •11. Вычисления в Лиспе.
- •13 . Внутреннее представление списков в Лиспе
- •14. Свойства символа Лиспа.
- •15. Ввод и вывод в Лиспе.
- •16.Основы рекурсии.
- •17.Простая рекурсия.
- •18.Другие виды рекурсии.
- •19.Функции более высокого порядка.
- •20.Применяющие функционалы.
- •21.Отображающие функционалы.
- •22.Замыкания.
- •23.Абстрактный подход в Лиспе.
- •24.Макросы.
- •25.Понятия. Числа. Символы. Списки. Строки. Последовательности. Массивы. Структуры.
- •26.Развитие языка лисп и лисп-системы. История лисПа. Лисп-системы. Лисп-машины.
24.Макросы.
Часто бывает полезно не выписывать вычисляемое выражение вручную, а сформировать его с помощью программы. Эта идея автоматического динамического программирования особенно хорошо реализуется в Лиспе, поскольку программа в этом языке также представляется в виде списка. При этом вычисление такого выражения или его части при необходимости можно предотвратить блокировкой (QUOTE), например, с целью преобразования выражения. Для вычисления же сформированного выражения программист всегда может вызвать интерпретатор (EVAL).
Перечисленные возможности можно использовать в Лиспе и без специальных средств. Однако наиболее естественно программное формирование выражений осуществляется с помощью специальных макросов . Внешне макросы определяются и используются так же, как функции, отличается лишь способ их вычисления. Вычисляя вызов макроса, сначала из его аргументов строится форма, задаваемая определением макроса. В результате вызова возвращается значение этой формы, а не сама форма, как было бы при вычислении функций. Таким образом, макрос вычисляется как бы в два этапа.
Макросы представляют собой абстрактный механизм, хотя и не чисто функциональный. С его помощью можно определить формирование и вычисление произвольной формы или целой программы.
Макросы дают возможность расширять синтаксис и семантику Лиспа и использовать новые подходящие для решаемой задачи формы предложений. Абстракции такого характера называют абстракциями проблемной области, а определяемое ими расширение языка Лисп - встроенным языком.
Макросы - это мощный рабочий инструмент программирования. Они дают возможность писать компактные, ориентированные на задачу программы, которые автоматически преобразуются в более сложный, но более близкий машине эффективный лисповский код. Однако с их использованием тоже связаны свои трудности и опасности. Создаваемые в процессе вычислений формы часто трудно увидеть непосредственно из определения макроса или из формы его вызова.
Синтаксис определения макроса выглядит так же, как синтаксис используемой при определении функций формы DEFUN:
(DEFMACRO имя лямбда-список тело)
Вызов макроса совпадает по форме с вызовом функции, но его вычисление отличается от вычисления вызова функции.
1)в макросе не вычисляются аргументы. Тело макроса вычисляется с аргументами в том виде, как они записаны
2)связано со способом вычисления тела макроса. Вычисление вызова макроса состоит из двух последовательных этапов. На первом этапе осуществляется вычисление тела определения с аргументами из вызова таким же образом, как и для функции.. На втором этапе вычисляется полученная из вызова раскрытая форма, значение которой возвращается в качестве значения всего макровызова.
Макрос - это форма, которая во время вычисления заменяется на новую, обычно более сложную форму, которая затем вычисляется обычным образом.
Макросы отличаются от функций и в отношении контекста вычислений. В этом смысле этап расширения макроса аналогичен вычислению функции, а этап последующего вычисления - нет. Во время расширения макроса доступны синтаксические связи из контекста определения. Вычисление же полученной в результате расширения, формы производится вне контекста макровызова, и поэтому статические связи из макроса не действуют. Следовательно, содержащее макровызов выражение эквивалентно выражению, в котором вызов заменен на его расширенную форму. Из-за такого определения контекста этапа вычисления макрос не во всех случаях можно заменить функцией, в теле которой имеется дополнительный вызов EVAL, даже если бы Лисп-система содержала функции типа NLAMBDA.