2010-08-15 8 views
8

Algunos afirman que un solo espacio de nombres en LISP conduce a macros antihigiénicos. http://community.schemewiki.org/?hygiene-versus-gensym¿Qué tiene un solo espacio de nombres que conduce a macros antihigiénicos? (en LISP)

http://www.nhplace.com/kent/Papers/Technical-Issues.html

¿Cuál es, precisamente, que trata de tener espacios de nombres individuales, dobles o múltiples que conduce a la higiene macro?

+1

Como no obtiene ninguna respuesta (real) aquí desde hace tres horas: puede intentar preguntar esto en "Lambda the Ultimate". Puede ser expulsado porque la lista es realmente acerca de la investigación en lenguajes de programación, pero las personas allí sin duda pueden responder a su pregunta. http://lambda-the-ultimate.org/ – Eike

Respuesta

7

Lisp-2 significa que tiene dos espacios de nombres: uno para las funciones, y otro para las demás cosas.

Esto significa que es menos probable que vuelva a vincular un valor de función (o valor var) en una macro, sin quererlo.

En Lisp-1, dado que hay un espacio de nombres, tiene (estadísticamente, pero no prácticamente) el doble de probabilidades de alcanzar una definición existente.

En realidad, Lisp-1s tiene la higiene cubierta con cosas como gensym y la amplia y confusa variedad de syntax-structure -como las macros que mantienen las cosas higiénicas.

Lo mejor que puedo decir es que el problema es principalmente un argumento del tipo "hombre de paja": es solo un problema en las implementaciones más pobres o antiguas.

Clojure ofrece macros higiénicas a través gensym o el lector macro myvar# (el # es esencialmente gensym).

Y usted no tiene que preocuparse de ámbito local revinculación de su función en sus macros, ya sea: Clojure es todo limpio:

user=> (defmacro rev [xs] `(reverse ~xs)) 
#'user/rev 
user=> (rev [1 2 3]) 
(3 2 1) 
user=> (let [reverse sort] (rev [1 2 5 3 6])) 
(6 3 5 2 1) 

Y aquí algo de higiene variables:

user=> (defmacro k [] (let [x# "n"] x#)) 
#'user/k 
user=> (k) 
"n" 
user=> (let [x "l"] (k)) 
"n" 
user=> (let [x "l"] (str (k) x)) 
"nl" 

Aviso nuestra sexy gensym 'd x#.

+4

En realidad, la macro 'rev' funciona principalmente debido a cómo Clojure resuelve automáticamente los símbolos introducidos por los literales en las formas de sintaxis, junto con el hecho de que los símbolos calificados para el espacio de nombres no pueden nombrar locals (el 'reverse' en realidad se convierte en' clojure.core/reverse' en la expansión; '(let [reverse: foo] (rev ...))' no es un problema, porque la expansión de la forma 'rev' nunca menciona' reverse' - menciona 'clojure.core/reverse'). Esto es, hasta donde yo sé, una contribución innovadora de Clojure al debate de la macro higiene. –

+3

Por supuesto 'gensym's son absolutamente cruciales aquí, pero un sistema de paquete (paquete es CL Lingo, eso es lo que la palabra" espacio de nombres "se utiliza en tierra Clojure) es fundamental para la sanidad macro no higiénica y la creación de Clojure es una forma particularmente inteligente de apretarlo para que sea de tanta ayuda como sea posible. –

+2

Olvidé por completo que la sintaxis-cita resuelve completamente los símbolos que incluye: ¡gracias por eso! Creo que mi respuesta es correcta, pero eso es algo importante/interesante de notar. De hecho, me aproveché de eso en una iteración anterior de mi respuesta a esta pregunta: http://stackoverflow.com/questions/3480377/clojure-namespace-management-is-there-a-way-to-save-and-restore -the-state-of-cl Gracias de nuevo, Michal, por aclarar las cosas. – Isaac

Cuestiones relacionadas