Las macros están destinadas a generar código, transformar código y proporcionar nuevas notaciones. Estas nuevas notaciones pueden ser más adecuadas para expresar mejor el programa, por ejemplo, proporcionando construcciones a nivel de dominio o nuevos lenguajes incorporados.
Las macros pueden hacer que el código fuente sea más autoexplicativo, pero la depuración puede ser más difícil. Como regla general, uno no debe usar macros cuando una función normal funcionará. Cuando los use, evite los escollos habituales, trate de atenerse a los patrones de uso común y las convenciones de nombres.
En comparación con las funciones, las macros se expanden en orden inverso; Primero lo primero, lo último lo último. Esto significa que, de forma predeterminada, no se puede usar una macro interna para generar la sintaxis necesaria para una macro externa.
A veces las macros necesitan mover los formularios proporcionados por el usuario. Uno debe asegurarse de no cambiar el orden en que se evalúan. El usuario puede estar confiando en los efectos secundarios que suceden en orden.
La expansión de una macro a menudo necesita usar el valor del mismo formulario proporcionado por el usuario más de una vez. Es posible que la forma tenga efectos secundarios o que esté llamando a una función costosa. Por lo tanto, la macro debe asegurarse de evaluar solo tales formas una vez. Por lo general, esto se hará asignando el valor a una variable local (cuyo nombre es GENSYM
ed).
Las macros complejas a menudo tienen partes de su lógica implementada en funciones separadas. Sin embargo, hay que recordar que las macros se expanden antes de compilar el código real. Al compilar un archivo, entonces, por defecto, las funciones y variables definidas en el mismo archivo no estarán disponibles durante la ejecución de la macro. Todas las definiciones de funciones y variables, en el mismo archivo, utilizadas por una macro deben estar envueltas dentro de una forma EVAL-WHEN
. EVAL-WHEN
debe tener las tres veces especificadas, cuando el código adjunto también debe evaluarse durante la carga y el tiempo de ejecución.
(eval-when (:compile-toplevel :load-toplevel :execute)
(defun foobar () ...))
Esto no se aplica a las funciones llamadas desde la expansión de la macro, solo a las llamadas por la macro misma.