¿Se expanden las macros cuando se compila el archivo?

13

Tengo una macro que necesita expandirse en cada instancia de su uso en tiempo de compilación. ¿Hay alguna manera de que pueda especificar que esto sea así sin pasar por la base de código y terminar cuidadosamente cada llamada eval-when-compile?

Sean Allred
fuente

Respuestas:

13

Todas las macros accesibles por el compilador de bytes se expanden durante la compilación. "Alcanzable" significa esencialmente no ser citado.

El cuerpo de defuns, defmacros, lambdas se compila en bytes cuando el archivo fuente que los contiene se compila en bytes. Entonces, sí, cualquier macro dentro de ellas se expandirá, siempre que no estén dentro de una cita ( '). Un error muy común es envolver lambdas en una cita y, de hecho, es por eso que nuncalambda debes citar tus s .

Esta es una de las grandes ventajas de las macros, siempre y cuando estén bien escritas, no tengan impacto en el rendimiento del tiempo de ejecución. La otra ventaja es su poder y versatilidad, por supuesto. La desventaja es que está manipulando la sintaxis, no los objetos, por lo que hay mucho espacio para problemas, algunos inesperados, otros inevitables.

Malabarba
fuente
7

Como Malabarba ya ha explicado, las macros se expanden durante la compilación de bytes. Si no se compila un archivo, las macros se expanden cuando se carga el archivo (expansión de macro ansiosa).

Sin embargo, no confíes en esto. Es muy mal estilo. En general, no puede esperar que el código que usa su macro se compile realmente, y generalmente debe ejecutar la menor cantidad de código posible durante la compilación. Específicamente, use macros escasamente y solo si no hay otra forma. Como regla general, use macros solo para sintaxis y nunca para semántica (o funcionalidad).

Las macros son una abstracción permeable. Su expansión está codificada en el código de destino en el momento de la compilación, y no se puede cambiar retrospectivamente. El código de destino depende posteriormente de la implementación específica de la macro en el momento de la expansión. Específicamente, depende de todas las API internas utilizadas en el cuerpo de la macro.

En consecuencia, no puede cambiar nada de esta API, ni nada en lo que se base la expansión de macros, sin romper ningún código compilado contra su macro.

El uso liberal de las macros para la funcionalidad allana el camino hacia el infierno de la dependencia .

Lunaryorn
fuente
Muy buenos puntos a tener en cuenta al escribir o usar macros.
Sean Allred
"El uso liberal de las macros para la funcionalidad allana el camino hacia el infierno de la dependencia". Hasta hace una semana, package.el tenía un error que rompía por completo la instalación del paquete en situaciones de macrodependencia perfectamente legítimas.
Malabarba
@Malabarba ¿Le gustaría proporcionar detalles?
lunaryorn
@lunaryorn Aquí tienes . Pequeño problema desagradable.
Malabarba
1
@lunaryorn Estoy de acuerdo en que las macros son peligrosas (incluso editaré mi respuesta para que suene menos elogiosa :), pero no creo que ese error haya sido una instancia específica. Ese error tenía otras manifestaciones (menos agravantes) que no involucran macros en absoluto. También causó problemas con las dependencias de funciones.
Malabarba