18. Macros

¿Recuerdas cuando en el primer capítulo mencionamos que los macros te permiten crear tu propio lenguaje de programación? Pedí que buscaras una silla. Ha llegado el momento.

Los macros son el arma secreta de Lisp desde 1958. Te permiten extender el lenguaje creando nuevas construcciones sintácticas, como si pudieras añadir páginas al propio libro de gramática. El código de un macro se ejecuta en tiempo de compilación: recibe código como dato, lo transforma y devuelve código nuevo. Es programar el programador.

Tu primer macro

(defmacro cuando [condicion & cuerpo]
  `(if ~condicion
     (do ~@cuerpo)))

(cuando true
  (println "Hola")
  (println "Mundo"))
;; Hola
;; Mundo
  • El acento grave (`) es la syntax quote: cita todo el código que le sigue.

  • ~ (unquote) evalúa una expresión dentro de la cita.

  • ~@ (unquote-splicing) inserta los elementos de una lista.

Este macro es exactamente lo que hace when por debajo. De hecho, puedes comprobarlo.

(macroexpand-1 '(when true (println "Hola")))
;; (if true (do (println "Hola")))

¿Cuándo usar macros?

Casi nunca. Y esa es la respuesta correcta. Las funciones resuelven el 99% de los problemas. Los macros son para ese 1% en el que necesitas controlar cuándo se evalúa el código, algo que las funciones no pueden hacer porque siempre evalúan sus argumentos antes de ejecutarse. Como decía Don Quijote: no todo lo que reluce es yelmo de Mambrino. No uses un macro donde una función basta.

Resumen

  • Los macros generan código en tiempo de compilación.

  • Se definen con defmacro.

  • Usan syntax quote (`) , unquote (~) y unquote-splicing (~@).

  • macroexpand-1 muestra el código generado.

  • Usa funciones siempre que puedas. Recurre a macros solo cuando necesites controlar la evaluación.

Ejercicios

  1. Usa macroexpand-1 para ver qué genera (and true false true).

  2. Crea un macro si que sea equivalente a if pero con sintaxis en español: (si condicion entonces sino).

This work is under a Attribution-NonCommercial-NoDerivatives 4.0 International license.

Will you buy me a coffee?

Visitors in real time

You are alone: 🐱