Les macros sont des fonctions. Ils prennent le code via leurs arguments et retournent le nouveau code. Les macros peuvent avoir des effets secondaires.
Votre code imprime quelque chose en tant qu'effet secondaire pendant l'expansion de macro et renvoie NIL
(le résultat de l'appel de la fonction FORMAT
).
(defmacro assign (name value)
(format t "assigning ~A to ~A~%" `,name `,value))
Son utilisation:
CL-USER 11 > (multiple-value-list (macroexpand '(assign foo bar)))
assigning FOO to BAR ; prints as a side effect
(NIL T) ; the macro expansion returns two values NIL and T
Il n'a pas de sens de citer les arguments. Le code est équivalent à ceci:
(defmacro assign (name value)
(format t "assigning ~A to ~A~%" name value))
Il retourne encore NIL
que l'expansion, ce qui est sans doute pas ce que vous voulez.
Si vous souhaitez que la macro développe un formulaire dans l'appel à format
, vous devez renvoyer cet appel sous la forme d'une liste. Ici, nous utilisons quasiquote
pour construire une liste à partir d'un modèle, en remplissant deux valeurs: name
et value
.
(defmacro assign (name value)
`(format t "assigning ~A to ~A~%" ,name ,value))
Peut-être que vous voulez citer le nom:
(defmacro assign (name value)
`(format t "assigning ~A to ~A~%" ',name ,value))
Les macros sont toujours développées avant de compiler, de sorte que le code compilé ne comprend que l'expansion. Si vous ne voulez pas que votre macro imprime la sortie pendant la macroexpansion, vous devez retourner le formulaire '(format ...)' au lieu de l'évaluer (placer une citation avant et enlever les deux que vous avez (ce qui n'est pas le cas quoi que ce soit en ce moment de toute façon)). – jkiiski