Las macros son esenciales para proporcionar acceso a las funciones de idioma. Por ejemplo, en TXR Lisp, tengo una sola función llamada sys:capture-cont
para capturar una continuación delimitada. Pero esto es incómodo de usar por sí mismo. De modo que hay macros alrededor, como suspend
o obtain
and yield
, que proporcionan modelos alternativos para la ejecución reanudable suspendida. Se implementan here.
Otro ejemplo es la macro compleja defstruct
que proporciona sintaxis para definir un tipo de estructura. Compila sus argumentos en lambda
-s y otro material que se pasa a la función make-struct-type
. Si los programas utilizados make-struct-type
directamente para definir estructuras de programación orientada a objetos, que sería feo:
1> (macroexpand '(defstruct foo bar x y (z 9) (:init (self) (setf self.x 42))))
(sys:make-struct-type 'foo 'bar '()
'(x y z)()
(lambda (#:g0101)
(let ((#:g0102 (struct-type #:g0101)))
(unless (static-slot-p #:g0102 'z)
(slotset #:g0101 'z
9)))
(let ((self #:g0101))
(setf (qref self x)
42)))
())
Huy! Están sucediendo muchas cosas que tienen que ser correctas. Por ejemplo, no solo insertamos 9
en la ranura z
porque (debido a la herencia) podríamos ser realmente la estructura base de una estructura derivada, y en la estructura derivada, z
podría ser una ranura estática (compartida por instancias). Estaríamos criticando el valor establecido para z
en la clase derivada.
En ANSI Common Lisp, un buen ejemplo de macro es loop
, que proporciona un sublengua completo para la iteración paralela. Una sola invocación a loop
puede expresar un algoritmo complicado completo.
Las macros nos permiten pensar independientemente sobre la sintaxis que nos gustaría en una función de idioma, y las funciones subyacentes o los operadores especiales necesarios para implementarla. Cualesquiera que sean las elecciones que hagamos en estos dos, las macros los unirán para nosotros. No tengo que preocuparme de que make-struct
sea feo de usar, por lo que puedo centrarme en los aspectos técnicos; Sé que la macro puede tener el mismo aspecto, independientemente de cómo realice varias concesiones. Tomé la decisión de diseño de que todas las funciones registradas en el tipo van a realizar todas las inicializaciones de estructuras. De acuerdo, eso significa que mi macro tiene que tomar todas las inicializaciones en la sintaxis de definición de ranura y compilar las funciones anónimas, donde la inicialización de la ranura se realiza mediante el código generado en los cuerpos.
Las macros son compiladores de bits de sintaxis, cuyas funciones y operadores especiales son el idioma de destino.
A veces las personas (las personas que no son Lisp, por lo general) critican las macros de esta manera: las macros no agregan ninguna capacidad, solo azúcar sintáctico.
En primer lugar, el azúcar sintáctico es una capacidad.
En segundo lugar, también debe considerar las macros desde una "perspectiva total de piratas informáticos": combinando macros con el trabajo a nivel de implementación. Si agrego funciones a un dialecto de Lisp, como estructuras o continuaciones, en realidad estoy ampliando la potencia. La participación de macros en esa empresa es esencial.Aunque las macros no son la fuente de la nueva potencia (no emana de las macros), ayudan a dominarla y aprovecharla, dándole expresión.
Si no tiene sys:capture-cont
, no puede simplemente modificar su comportamiento con una macro suspend
. Pero si no tiene macros, entonces tiene que hacer algo terriblemente inconveniente para proporcionar acceso a a una nueva función que no es una función de biblioteca, es decir, codificar algunas reglas de estructura de frase nuevas en un analizador.
Esta pregunta tiene un sentido de CW, así que publiqué como tal. –
Pero, ¿qué tienen las macros que las hacen superiores a escribir lenguajes específicos de dominio sobre funciones normales? –
JtS: Necesitaría una gran cantidad de citas (sin duda una función relacionada) para retrasar la evaluación de todo, por ejemplo. Las macros te permiten evitar eso al permitirte hacer cosas arbitrarias en tiempo de compilación. – Ken