Las macros higiénicas son las macros cuya extensión se garantiza para no causar colisiones con definiciones existentes del símbolo. Son una característica de lenguajes de programación tales como esquema y Dylan .
En un lenguaje de programación que tenga macros antihigiénicas, es posible que los atascamientos variables existentes sean ocultados de una macro por los atascamientos variables que se crean durante su extensión. En el C, este problema se puede ilustrar por el fragmento siguiente:
#define INCI (i) {internacional a=0; ++i;} cañería de la internacional () { internacional a = 0, b = 0; INCI (a); INCI (b); printf (" a ahora es %d, b ahora es %d \ n", a, b); }
El funcionamiento del antedicho a través del preprocesador C produce:
cañería de la internacional () { internacional a = 0, b = 0; {internacional a=0; ++a;}; {internacional a=0; ++b;}; printf (" a ahora es %d, b ahora es %d \ n", a, b); }
La variable “a” declarada en el alcance superior nunca es alterada tan por la ejecución del programa, pues el resultado del programa compilado demuestra:
a ahora es 0, b ahora es 1 Observar que algunos compiladores C, tales como GCC, tienen una opción como “- Wshadow” que advierta cuándo una variable local sombrea una variable global, que habría cogido el problema antedicho.
El " problem" de la higiene; puede extender más allá de atascamientos variables. Considerar este campo común balbucean macro de :
(defmacro mi-a menos que (cuerpo &body de la condición) `(si (no, condición) (progn , @body)))
Mientras que no hay referencias a las variables en esta macro, asume el " de los símbolos; if", " not", y " progn" son todos limitan a sus definiciones de función generalmente. Si, no obstante la macro antedicha se utiliza en el código siguiente:
(flet ((no (x) x)) (mi-a menos que t (" del formato t; ¡Esto no debe ser impresa! ")))
Porque la definición del " not" localmente se ha alterado, el " del mensaje; ¡Esto no debe ser impresa! " será impreso, que no es probablemente el comportamiento previsto. El problema puede ser fijado manualmente insertando el objeto deseado de la función en el valor de vuelta de la macro.
(defmacro mi-a menos que (cuerpo &body de la condición) “(si (funcall”, # ' no, condición) (progn , @body)))
. Si el programador necesita utilizar almacenamiento temporal durante la extensión de una macro, él puede utilizar uno con un nombre inusual y esperar que el mismo nombre nunca será utilizado en un programa que utilice su macro.
Creación temporal del símbolo del . En algunos lenguajes de programación es posible para un nuevo nombre variable, o el símbolo, ser generado y estar limitado a una localización temporal. El sistema que del tratamiento de lenguas se asegura que eso que esto nunca coincide con otro nombre o localización en el ambiente de la ejecución. La responsabilidad de elegir utilizar esta característica dentro del cuerpo de una definición macra se deja al programador. Este método fue utilizado en el MacLisp, donde una función nombró el " gensym" podía ser utilizado para generar un nuevo nombre del símbolo. Las funciones similares existen en muchos Balbucear-como idiomas, incluyendo el campo común extensamente ejecutado balbucean [#gensym del HTTP //www.com/documentation/HyperSpec/Body/f_gensym.htm] estándar, generalmente nombrado gensym.
Transformación higiénica . El procesador responsable de transformar los patrones de la forma de la entrada en una forma de salida detecta choques del símbolo y los resuelve temporalmente cambiando los nombres de símbolos. Esta clase de proceso es apoyada por el " de Scheme's; dejar-syntax" y " definir-syntax" sistemas macros de la creación. La estrategia básica es identificar los atascamientos del en la definición macra y substituir esos nombres por los gensyms, e identificar las variables libres del en la definición macra y cerciorarse de esos nombres se miran para arriba en el alcance de la definición macra en vez del alcance donde la macro fue utilizada.
¡(intercambio del definir-sintaxis! (sintaxis-reglas () ((_ un b) (dejar ((valor a)) ¡(fijar! un b) ¡(fijar! valor de b)))))
¡(intercambio del definir-sintaxis! (lambda (stx) (stx del sintaxis-caso () ((_ un b) (sintaxis (dejar ((valor a)) ¡(fijar! un b) ¡(fijar! valor de b)))))))
¡(intercambio del definir-sintaxis! (sc-macro-transformador (lambda (ambiente de la forma) (dejar ((a (ambiente del hacer-sintáctico-encierro '() (la forma del cadr))) (b (ambiente del hacer-sintáctico-encierro '() (forma del caddr)))) `(dejar ((el temp, a)) ¡(fijar!, a, b) ¡(fijar!, temp de b))))))
(lazo del definir-sintaxis (transformador (lambda (x r c) (dejar ((cuerpo (cdr x))) `(, (llamar-con-actual-continuación de r ') (, (lambda) de r '(salida) (, (r 'dejaron), (r 'f) (), @body (, (r 'f)))))))))
.
| Random links: | Condado de Madison, Nueva York | Rudolf Carnap | Harlan, Iowa | Sandra Beckwith | Sun salino magnífico |