2012-01-03 18 views
7

Lo siento por el título terriblemente vaga :)Clojure - Citando Confusión

Soy nuevo a las macros y estoy teniendo problemas para entender la diferencia entre estas dos afirmaciones:

`(+ 1 2 ~(+ 2 3)) ; => (clojure.core/+ 1 2 5) 
'(+ 1 2 ~(+ 2 3)) ; => (+ 1 2 (clojure.core/unquote (+ 2 3))) 

Cuando les funciono sin el fin de la cita , parecen bastante idénticos aparte de la calificación?

`(+ 1 2 (+ 2 3)) ; => (clojure.core/+ 1 2 (clojure.core/+ 2 3)) 
'(+ 1 2 (+ 2 3)) ; => (+ 1 2 (+ 2 3)) 

Así que, básicamente, estoy confundido por `vs '. Según tengo entendido, ambos citan todo lo que hay en la lista, por lo que no estoy seguro de por qué el comitente no se comporta de manera diferente. Básicamente `se comporta de la manera en que esperaría que tanto` como 'se comporten.

Gracias!

Respuesta

10

La respuesta corta es que el uso de comillas solo funciona dentro de una cita hacia atrás. En una expresión citada normal, todo (incluido ~ y todo dentro/detrás) se pasa como está, mientras que dentro de una expresión entrecomillada, se evalúa todo dentro/detrás de ~ (pero todo lo demás permanece sin evaluar). Por lo tanto, no, no todo lo que está dentro de una expresión entrecomillada permanece sin evaluar: puede usar ~ en su interior, para usarlo como un tipo de plantilla, donde "completa los espacios en blanco" con ~.

Editar: Para cotización (nunca mejor dicho) la documentation relevante a su pregunta:

Cita:

Quote (') 
'form => (quote form) 

y (desde la sección special forms):

(formulario de cotización) Produce la forma no evaluada

user=> '(a b c) 
(a b c) 

Nota hay ningún intento de llamar a la función a. El valor de retorno es una lista de 3 símbolos.

Sintaxis comilla (también llamado quasiquote, backquote):

para las listas/Vectores/Juegos/Mapas, la sintaxis de comillas establece una plantilla de la estructura de datos correspondiente. Dentro de la plantilla, las formas no calificadas se comportan como si se citaran sintaxis recursiva, pero los formularios pueden ser exentos de dicha cita recursiva calificándolos con un comillas o unquote-splicing, en cuyo caso se tratarán como expresiones y se reemplazarán en la plantilla por su valor, o secuencia de valores, respectivamente.

+1

También se podría mencionar el gran papel [Cita Cuasi en Lisp por Alan Bawden] (http://www.scribd.com/doc/47702904/Bawden-Quasi-Quotation-in-Lisp). – Daimrod

+0

Daimrod, sí, ¡gracias por el enlace! (Nota para principiantes: Hay algunas diferencias entre otros dialectos Lisp y Clojure. Por ejemplo, en CL y en el papel, ',' (espacio en blanco en Clojure) se usa para desmarcar. Además, en CL, a ',' fuera de la expresión backquoted no es válida (generalmente es un error del lector).) – danlei

+0

Gracias, no me di cuenta que el desvinculación estaba reservado para la sintaxis-cita. Eso definitivamente explica los resultados. Estoy pasando por Joy of Clojure y me he detenido en el capítulo de Macro para experimentar y tratar de entender estas cosas, por lo que es posible que haya extrañado explicaciones en el capítulo :) – anonymous

4

Intente ejecutar eval en los resultados de sus primeras dos expresiones. El primero, con `," se expande "a (+ 1 2 3), que muy bien se evalúa a 6. El segundo, con '," se expande "a (+ 1 2 (unquote (+ 1 2))), y la anotación no es válida en ese contexto ya que ya no está dentro de una cita! Así que esto no se evalúa del todo.

Básicamente hay dos diferencias entre 'y `:

  • ` espacio de nombres califica todo
  • `permite unquoting