Макросы и байткодирование
Вы можете спросить, зачем мы тратим время на вычисление развёртывания макроса и последующее его вычисление. Почему бы макросу не производить желаемые результаты напрямую? Причина связана с компиляцией.
Когда вызов макроса появляется в программе Lisp, которая компилируется, компилятор Lisp вызывает определение макроса так же, как и интерпретатор, и получает развёртывание. Но вместо того, чтобы вычислять это развёртывание, он компилирует развёртывание так, как будто оно появилось непосредственно в программе. В результате скомпилированный код производит значение и побочные эффекты, задуманные для макроса, но выполняется со скоростью, характерной для полностью скомпилированного кода. Это не сработало бы, если бы тело макроса само вычисляло значение и побочные эффекты — они были бы вычислены во время компиляции, что бесполезно.
Для того, чтобы компиляция вызовов макросов работала, макросы должны быть уже определены в Lisp, когда вызовы к ним компилируются. Компилятор имеет специальную функцию, чтобы помочь вам в этом: если файл, который компилируется, содержит форму defmacro, макрос будет временно определён на весь остаток компиляции этого файла.
Байткодирование файла также выполняет все вызовы require на верхнем уровне в файле, поэтому вы можете убедиться, что необходимые определения макросов доступны во время компиляции, потребовав файлы, которые их определяют (см. Названные особенности). Чтобы избежать загрузки файлов определений макросов, когда кто-то выполняет скомпилированную программу, запишите eval-when-compile вокруг вызовов require (см. Вычисление во время компиляции).
Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Compiling-Macros.html