greenbeer wrote:Hello!
Is it possible in common lisp to write macro which interprets part of arguments like defmacro and other part like defun?
For example, something like:
Code: Select all
(def-amazing-macro leopard (dog &value cat)
`(if ,dog "war is over" cat))
(let ((x "happy old year"))
(leopard (> 4.99 5) x))
;; it should give:
"happy old year"
No matter what the value of CAT is, you've typed the symbol in a quoted list. Whether CAT is evaluated at macroexpansion time or at run time, you haven't referred to it anywhere. Quasiquoting doesn't have anything to do with macros. It's just shorthand that lets you avoid writing LIST and ' a bunch of times. If you'd written your macro properly, it
would behave like you want it to.
Code: Select all
(defmacro leopard (dog cat)
`(if ,dog "war is over" ,cat))
(macroexpand '(leopard (> 4.99 5) x)) => (IF (> 4.99 5) "war is over" X)
This gives the answer you wanted.
If you just want to ensure that CAT is only evaluated once in the macroexpanded code, or is always evaluated, then return `(LET ((CAT ,CAT)) (IF ,DOG "war is over" CAT)). Note that if the code in DOG refers to any variables named CAT, that binding will be clobbered. You can fix that with a gensym.