Quiero demostrar mi falta de conocimiento con un ejemplo.
Usando las siguientes dos definiciones de macro,
(defmacro for (var from init to final do &rest body)
"Execute a simple for loop: (for i from 1 to 10 do (print i))."
(let ((tempvar 'max))
`(let ((,var ,init)
(,tempvar ,final))
(while (<= ,var ,tempvar)
,@body
(setq ,var (1+ ,var))))))
(defmacro for (var from init to final do &rest body)
"Execute a simple for loop: (for i from 1 to 10 do (print i))."
(let ((tempvar (make-symbol "max")))
`(let ((,var ,init)
(,tempvar ,final))
(while (<= ,var ,tempvar)
,@body
(setq ,var (1+ ,var))))))
la primera macro sombrea cualquier variable nombrada max
que pueda ocurrir en el cuerpo y la segunda no, lo que se puede mostrar con el siguiente ejemplo:
(let ((max 0)) ;; this variable is shadowed if the first macro defintion is used
(for i from 1 to 3 do
(setq square (* i i))
(if (> square max)
(princ (format "\n%d %d" i square)))))
Hasta donde sé, la evaluación de una llamada macro funciona así:
La macro se evalúa dos veces. Primero se evalúa el cuerpo y devuelve un formulario. Este formulario luego se evalúa nuevamente.
Hasta aquí todo bien.
Pero si supongo que la macro realmente devuelve un fragmento de texto que resulta ser una forma de ceceo, que luego se interpreta, obtengo un conflicto que me impide comprender el ejemplo anterior.
¿Qué parte del texto make-symbol
devuelve la segunda macro que usa , para que no se sombree? En mi opinión, un nombre de símbolo elegido aleatorio extremadamente improbable tendría sentido.
Si uso pp-macroexpand...
ambas macros, devuelvo la misma expansión.
¿Alguien puede ayudarme a salir de esta confusión?
print-gensym
y print-circle
que t
usted será capaz de ver la diferencia en las expansiones de macro.
#:max
. Qué significa eso ? Estoy muy interesado en más detalles.
#:
es simplemente una convención de la impresora para indicar un símbolo uninterned (esto es lo que print-gensym
se enciende), hay más detalle en el manual: (elisp) Creating Symbols
.