macros - ejemplos - macro variables definicion
¿Qué puede salir mal cuando defino una macro y simplemente uso un nombre bastante raro para una variable temporal? (2)
El problema surge cuando reutiliza su propia macro en otro contexto y sus variables hábilmente basadas en el nombre son efectivamente redundantes, ya que todas están en el mismo espacio de nombres.
Puedo pensar en un ejemplo cuando se utiliza un cierre que accede a una variable en un encierre (let)
, pero se pasa a una macro que también usa un adjunto (let)
define una variable "segura" con un choque de nombre. Es un ejemplo artificial, lo siento, no puedo pensar en un caso real en este momento.
(defmacro my/a (x)
(let ((my/safe-name x))
`(progn ,(my/b (lambda () my/safe-name))
,my/safe-name)))
(defmacro my/b (f)
`(let ((my/safe-name 4))
(when (evenp (funcall ,f))
(print "F is even!"))))
(my/a 3) ; will print "F is even", but it shouldn''t
Let Over Lambda Capítulo 3 Sección ''Captura no deseada'' dice:
"Seguramente podemos pensar en nombres suficientemente raros para que el problema nunca aparezca. Sí, en muchos casos, los paquetes y los nombres de variables inteligentes pueden resolver el problema de la captura variable. Sin embargo, la mayoría de los errores de captura variables no surgen en el código directamente. creado por un programador. La mayoría de los problemas de captura variable solo surgen cuando otras macros usan su macro (se combinan con su macro) de una forma que no anticipaba " .
y luego no me da un ejemplo para la parte audaz. ¿Cuál sería uno de esos ejemplos? Imagina un hipotético equipo de desarrollo de Lisp donde su loco jefe prohíbe el uso de gensym o cualquier cosa que genere símbolos no identificados y los programadores simplemente recurren a tirar dados alfanuméricos para encontrar nombres de variables aleatorias como temp-27s63f8sk2n o sum-3t84hj4df cada vez que extrañan gensym. ¿Cuál sería un ejemplo donde el equipo se meterá en problemas?
Hablando de eso, Emacs 24.3.1 define dotimes y dolist sin usar símbolos no internados. Extraño.
OK, entonces propongo automatizar ese proceso de "tirar dados alfanuméricos". Por supuesto, no tiene que ser aleatorio, puedes usar un contador. Además, sería bueno poder especificar un prefijo, para la depuración. Oh, espera, eso es exactamente lo que hace gensym
.