respuesta original
Creo que esto es lo que busca:
(defmacro is [expr value]
`(if (= ~expr ~value)
true
(println "Expected " ~value "In" (str (quote ~expr))
"But Evaluated to" ~expr)))
lo (quote ~expr)
no es llevar el s-expresión que constituyen expr
en su "plantilla", pero lo impide de ser evaluado, luego aplicar str
a la expresión-s no evaluada lo convierte en una cadena para la concatenación con las otras cadenas del mensaje de error. Por lo tanto,:
user=> (is (+ 2 2) 5)
Expected 5 In (+ 2 2) But Evaluated to 4
produce el comportamiento deseado.
En lugar de utilizar 'yes
reportar el éxito, puede simplemente usar true
como el informe para el éxito de la prueba, dando:
user=> (is (+ 2 2) 4)
true
y evitar el problema de 'yes
que se devuelven como un símbolo cualificado. Si necesita un símbolo, por alguna razón, entonces se podría hacer una palabra clave:
(defmacro is [expr value]
`(if (= ~expr ~value)
:yes
(println "Expected " ~value "In" (str (quote ~expr))
"But Evaluated to" ~expr)))
user=> (is (+ 2 2) 4)
:yes
respuesta a pregunta planteada en Comentarios
Pediste en los comentarios:
Lamento haber sido más claro en mi pregunta. ¿Cuál sería la diferencia entre un símbolo y una palabra clave en este caso?
Tenga en cuenta su definición original (con la corrección a que el error devuelve la forma en que quería):
(defmacro is [expr value]
`(if (= ~expr ~value)
'yes
(println "Expected " ~value "In" (str (quote ~expr))
"But Evaluated to" ~expr)))
Imagino que desea que el pensamiento 'yes
que se puede utilizar para probar contra 'yes
en otra contextos (a menudo se ve este tipo de pruebas en textos introductorios de ceceo). Pero 'yes
se utiliza en su macro definición, se vuelve un símbolo cualificado cuando la prueba es pases:
user=> (is (+ 2 2) 4)
user/yes
Ahora, esto no es lo que cabe esperar.Imagínese que usted ha dicho esto:
user=> (= 'yes (is (+ 2 2) 4))
false
para obtener una respuesta true
, que tendría que decir esto (utilizando el precio de sintaxis):
user=> (= `yes (is (+ 2 2) 4))
true
Si ha definido su macro para volver :yes
, entonces obtener la devolución comprobable sin necesidad de sintaxis cita el objeto que está utilizando para hacer la revisión:
user=> (= :yes (is (+ 2 2) 4))
true
Pero todo esto es innecesario ya que realmente son i INTERESADAS en (+ 2 2)
si vuelve 4
, es decir, si su afirmación es true
o false
en lugar de si 'yes
es igual a `` sí or
'sí ; you can just have it return
true` y evita este paso de comprobación (en el mundo real).
En cualquier caso, para comprender qué son los símbolos calificados, debe leer docs on the clojure reader y this SO answer explaining the ins and outs of symbols in clojure.
Gracias. Pero, ¿por qué lo convirtió en una palabra clave? ¿Cuál sería la diferencia? – unj2
El problema con el símbolo citado es que aparece como un símbolo calificado, como ha señalado. Sugerí usar 'verdadero' como el mejor reemplazo, pero descarté la opción de usar una palabra clave si, por alguna razón, necesitabas algo 'parecido a un símbolo' por razones que tenían que ver con la forma en que escribiste el resto del programa. Creo, sin embargo, que "verdadero" es el camino a seguir en abstracto. – Pinochle
Lo siento, debería haber sido más claro en mi pregunta. ¿Cuál sería la diferencia entre un símbolo y una palabra clave en este caso? – unj2