Réponse originale
Je pense que c'est ce que vous cherchez:
(defmacro is [expr value]
`(if (= ~expr ~value)
true
(println "Expected " ~value "In" (str (quote ~expr))
"But Evaluated to" ~expr)))
ce que (quote ~expr)
n'est apporter le s-expression représentée par expr
dans votre « modèle », mais empêche d'être évalué, puis en appliquant str
à l'expression s non évaluée, il en fait une chaîne de concaténation avec les autres chaînes du message d'erreur. Ainsi,:
user=> (is (+ 2 2) 5)
Expected 5 In (+ 2 2) But Evaluated to 4
produit le comportement souhaité.
Plutôt que d'utiliser 'yes
signaler le succès, vous pouvez simplement utiliser true
comme le rapport pour le succès de l'épreuve, ce qui donne:
user=> (is (+ 2 2) 4)
true
et en évitant le problème de 'yes
être retourné comme un symbole qualifié. Si vous avez besoin d'un symbole pour une raison quelconque, vous pourriez faire un mot-clé:
(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
Réponse à la question posée dans les commentaires
Vous avez demandé dans les commentaires:
Je suis désolé d'avoir été plus clair dans ma question. Quelle serait la différence entre un symbole et un mot-clé dans ce cas?
Tenez compte de votre définition originale (avec la correction à faire l'erreur retour la façon dont vous voulez):
(defmacro is [expr value]
`(if (= ~expr ~value)
'yes
(println "Expected " ~value "In" (str (quote ~expr))
"But Evaluated to" ~expr)))
Je suppose que vous voulez que la pensée 'yes
que vous pouvez utiliser pour tester contre 'yes
dans d'autres contextes (on voit souvent ces types de tests dans des textes de lisp d'introduction). Mais 'yes
est utilisé dans la définition macro, elle retourne un symbole qualifié lorsque le test est passe:
user=> (is (+ 2 2) 4)
user/yes
Maintenant, ce n'est pas ce que vous voulez.Imaginez que vous avez dit ceci:
user=> (= 'yes (is (+ 2 2) 4))
false
Pour obtenir une réponse true
, vous auriez à dire (en utilisant une citation de syntaxe):
user=> (= `yes (is (+ 2 2) 4))
true
Si vous définissez votre macro pour revenir :yes
, vous obtenir le retour checkable sans avoir à la syntaxe citation l'objet que vous utilisez pour faire la vérification:
user=> (= :yes (is (+ 2 2) 4))
true
Mais tout cela est superflu parce que vous êtes vraiment i INTERESSEES en si (+ 2 2)
retours 4
, à savoir si votre affirmation est true
ou false
plutôt que si 'yes
égale `` oui or
« oui ; you can just have it return
true` et éviter cette étape de contrôle (dans le monde réel).
Dans tous les cas, pour comprendre ce que sont les symboles qualifiés, vous devez lire les docs on the clojure reader et this SO answer explaining the ins and outs of symbols in clojure.
Merci. Mais pourquoi en avez-vous fait un mot-clé? Quelle serait la différence? – unj2
Le problème avec le symbole cité est qu'il apparaît comme un symbole qualifié, comme vous l'avez noté. J'ai suggéré d'utiliser 'true' comme le meilleur remplacement, mais j'ai rejeté l'option d'utiliser un mot-clé si, pour une raison quelconque, vous aviez besoin de quelque chose de 'symbolique' pour faire comme le reste du programme. Je pense, cependant, que «vrai» est la voie à suivre dans l'abstrait. – Pinochle
Je suis désolé d'avoir été plus clair dans ma question. Quelle serait la différence entre un symbole et un mot-clé dans ce cas? – unj2