Esta respuesta no se trata tanto de Clojure, sino de Lisp y macros en general.
Recuerde:
APLICAR está ahí para ser capaz de llamar a las funciones con las listas de argumentos que se crean en tiempo de ejecución.
Las macros están ahí para generar un nuevo código fuente a partir de algún código fuente, y se ejecutará el código fuente generado.
Ahora:
Si permite que aplicará a los piensos diferente código fuente en una macro en tiempo de ejecución, uno tiene que ser capaz de generar el código de resultado en tiempo de ejecución y también para ejecutar el código generado.
Por lo tanto, en un sistema Lisp compilado, cada llamada de APLICAR con una macro crea potencialmente un nuevo código que debe compilarse en tiempo de ejecución para poder ejecutarlo. Esto significa también que puede obtener nuevos errores de compilación en tiempo de ejecución, cuando su código se está ejecutando y el código tiene algún problema. Entonces, para APLICAR macros en tiempo de ejecución, necesita un compilador y toda la información necesaria (por ejemplo, otras macros) para poder expandir y compilar el código.
Esto también significa que, en el caso general, no se puede compilar APLICAR con una macro antes del tiempo de ejecución, ya que no se sabe qué argumentos de ejecución se aplicarán.
En un Lisp basado en intérprete, puede haber más información y se pueden aplicar macros todo el tiempo.
En los primeros Lisp había funciones normales y los llamados FEXPR. Los FEXPR permitieron llamadas flexibles y manipulación del código de tiempo de ejecución. Más adelante en la historia de Lisp se han reemplazado con macros, ya que las macros permiten una compilación eficiente y, en los sistemas basados en el compilador, permiten que los errores de sintaxis se manejen antes del tiempo de ejecución.