2010-09-21 18 views
7

¿Es posible escribir una macro en Clojure que genere más de un valor o expresión? Para mí, parece que no es posible, al menos no mediante el uso de la plantilla de cita de sintaxis `(..).¿Cómo escribo una macro Clojure para crear más de una expresión?

p. Ej. a partir de: [1 4] través de [1 (mr 2 3) 4] a [1 2 3 4]

o a partir de:

(do 
    (prn 1) 
    (prn 4)) 

a través de:

(do 
    (prn 1) 
    (mr 2 3) 
    (prn 4)) 

a:

(do 
    (prn 1) 
    (prn 2) 
    (prn 3) 
    (prn 4)) 

Respuesta

10

Una macro expande una forma en otra forma, por lo que no puede tener una macro devolver dos f completamente independientes orms. Sin embargo, puede hacer que devuelva formularios compuestos como do declaraciones que hacen un montón de cosas.

(defmacro foo [n] 
    `(do [email protected](map #(list println %) n))) 

Para su ejemplo anterior se puede poner la macro alrededor de la forma que desea modificar:

(expand-mr 
(do 
    (prn 1) 
    (mr 2 3) 
    (prn 4))) 

macros están diseñados para ser seguros y, como tales, no se puede modificar nada fuera de su propio alcance. Actualmente, una macro obtiene una s-expresión y la convierte en otra s-expresión más útil o útil. Para que una macro devuelva dos expresiones s separadas, debería modificar su expresión adjunta. La sintaxis debería ser radicalmente diferente y no tengo claro cómo se haría con s-expressions. La solución de esto es expandir el alcance de la macro para incluir todo lo que necesita modificar.

+0

Gracias Arthur! Ya estaba esperando esa respuesta, pero es bueno estar seguro. – Stefan

+0

¿Pero puede darme un ejemplo de cómo una macro que devuelve dos formularios independientes puede causar un problema de seguridad, pero de lo contrario es seguro? Creo que el alcance sigue siendo el mismo. – Stefan

+0

Estoy usando el término 'seguro' para disculparme por eso. Editaré para expandir eso. –

Cuestiones relacionadas