Каковы типичные приложения макросов Lisp?

19

Я пытаюсь изучить некоторые LISP, и я много читал о важности макросов LISP, поэтому я хотел бы получить некоторый опыт работы с ними.

Можете ли вы предложить практическую область применения, которая позволила бы мне использовать макросы для решения реальной проблемы и понять полезность этой конструкции программирования?

НОТА

Это не общий, какой проект я должен сделать следующий вопрос. Мне интересно понять, какие проблемы обычно решаются с помощью макросов LISP. Например, они хороши для реализации абстрактных типов данных? Почему эта конструкция была добавлена ​​в язык? Какие проблемы он решает, которые не могут быть решены с помощью простых функций?

Джорджио
источник

Ответы:

9

Макросы Lisp сочетают в себе несколько различных свойств:

  1. Макросы определяют новый синтаксис ↔ они используют исходный код в качестве ввода
  2. Макросы обычно запускаются во время компиляции
  3. Макросы генерируют исходный код

Лучшие приложения используют все эти аспекты. Вероятно, наиболее известным примером является (цикл ...) в Common Lisp, он не был бы близко к его полезности без одной из этих функций. Без источника в качестве входных данных было бы неудобно определять действия внутри цикла; без расширения во время компиляции это было бы слишком медленно; и без генерации кода он не был бы исполняемым.

Другим прекрасным примером является глава двоичной сериализации в Практическом общем Лиспе , Практическом разделе : Анализ двоичных файлов .

Макрос запроса, который реализует что-то похожее на LINQ, может быть другим хорошим приложением. Но было бы не хватать автозаполнения, которое делает LINQ таким же приятным, как и он. Почти все, что сегодня решается специальными генераторами кода с входами XML (например, XAML), также может быть реализовано с помощью макросов Lisp.

Патрик
источник
Я только что купил книгу «Практический общий Лисп», я посмотрю на предложенный вами пример.
Джорджио
2

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

Пол Грэм в «На Лиспе» (IMHO) дает одно из лучших описаний различий между макросами и функциями, а также обсуждает их совпадение и уникальность. Многие биты кода могут быть написаны либо как функция, либо как макрос, но в некоторых случаях будет работать только макрос. Как только вы обернетесь вокруг этого, я думаю, у вас есть смысл макросов в LISP.

В качестве примера макроса, где функция не будет работать, посмотрите 'aif' (анафорический if). Это всего лишь несколько строк кода и моя рекомендация, с чего начать.

И сделайте ссылку на версию anaphoric Common Lisp if, которая использует преднамеренный захват переменных. Автоматически гигиеническая версия схемы не является IMO «реальной сделкой». Перехват переменных является важной частью макропрограммы LISP, и некоторые из более мощных и полезных макросов, безусловно, используют его в своих интересах.

Клейтон Стэнли
источник