我有这个宏:
(defmacro if (test-form &body body)
(let ((test (gensym)))
`(let ((,test (cl:if (booleanp ,test-form)
(cl-truth ,test-form)
,test-form)))
(cl:if ,test
,@body))))
使用它的结果是:
LO> (if (wordp (wordify ""))
(print 1)
(print 0))
NIL
(您可以看到,我在一个由lo
组成的包中工作,但在 中。——该函数用于创建对应的 的实例。谓词检查谓词的输出是否为。然后返回第二个值。):use
common-lisp
cl:if
:shadow
wordify
make-word
defstruct
booleanp
=> TRUE, t
=> FALSE, nil
cl-truth
macroexpand-1
在这里没有用。它返回=> NIL, NIL
如果我尝试考虑可能的输出,我会发现destructuring-bind
一个有用的工具:
(destructuring-bind (test-form &body body)
'((wordp (wordify "")) (print 1) (print 0))
(let ((test (gensym)))
`(let ((,test (cl:if (booleanp ,test-form)
(cl-truth ,test-form)
,test-form)))
(cl:if ,test
,@body))))
输出为:
(LET ((#:G698
(COMMON-LISP:IF (BOOLEANP (WORDP (WORDIFY "")))
(CL-TRUTH
(WORDP (WORDIFY "")))
(WORDP (WORDIFY "")))))
(COMMON-LISP:IF #:G698
(PRINT
1)
(PRINT
0)))
结果就是期望的:
1
; No value
print
(这是使用princ
没有返回值的习惯。)
你能告诉我为什么宏的行为不同吗?
非常感谢。
编辑:
只是添加一个可能更合适的宏版本,但没有解决奇怪的行为。
(defmacro if-c (test-form instructionlist1 &optional instructionlist2)
(let ((test (gensym)))
`(let (;; The general Logo testform will return => TRUE, T / FALSE, NIL
(,test (destructuring-bind (logo &optional cl)
(multiple-value-list ,test-form)
(cl:if (booleanp logo)
cl
(error "if doesn't like ~a as input"
logo)))))
(cl:if ,test
,instructionlist1
,instructionlist2))))
编辑2:
我忘了说了:是的,奇怪的行为已经解决了。简单地说,包上方的宏LC
并没有在包中展开,LO
而是展开了下面的宏:
(defmacro if (test-form &body body)
())
LO
在我决定将它移至 之前,它是我准备定义它的地方的残留部分LC
。