我定义了以下宏:
(defmacro ~lazy (expression)
`(lambda ()
,@expression))
(defgeneric force~ (value)
(:method (value)
value)
(:method ((value function))
(funcall value)))
(defmacro ~~ (expression)
`(~lazy (force~ ,expression)))
[...] 以下宏定义了名称“NAME”的通用函数,并定义了一些标准方法。这应该像'REDUCE'一样工作并且在返回惰性值时强制所有延迟值,当它甚至一次遇到惰性值和非惰性值时(否则以宏开头并以'〜'结尾)。
(defmacro ~lazy-reduce~ (name reduce-fun (arg-var args-var)
&body methods)
(let ((first (gensym "first")))
`(defgeneric ,name (,arg-var ,args-var)
,@(append
(if (not (member `(,arg-var (,args-var cons))
methods
:key #'car
:test #'equal))
`((:method (,arg-var (,args-var cons))
(let ((,first (first ,args-var)))
(if (functionp ,first)
(~~ (,reduce-fun (force~ ,first)
(force~
(,name ,arg-var
(rest ,args-var)))))
(,name (,reduce-fun ,arg-var ,first)
(rest ,args-var)))))))
(if (not (member `((,arg-var function)
,args-var)
methods
:key #'car
:test #'equal))
`((:method ((,arg-var function)
,args-var)
(~~ (,name (force~ ,arg-var)
,args-var))))))
,@(mapcar (lambda (method)
(cons :method method))
methods))))
现在我定义〜_AND~就像这样:
(~lazy-reduce~ ~_and~ and (val vals)
(((val null)
vals)
nil)
((val (vals null))
val))
调用
(~_and~ t (list 2))
工作正常并按预期返回'2',但
(force~ ~_and~ t (list (~ 2)))
只返回'T'。
我不知道为什么会这样,它阻止我简明地定义'~FIND-IF'。
答案 0 :(得分:0)
我发现了我的错误:〜_AND~的第一种方法如下:
(:method (val (vals cons))
(let ((first (first vals)))
(if (functionp first)
(~~ (and (force~ first)
(force~ (~_and~ val (rest vals)))))
(~_and~ (and val first)
(rest vals)))))
(这可以通过给定定义~_AND~的MACROEXPAND-1看到)
这意味着所显示的呼叫被评估为(大致)为
(and (force~ (~ 2))
T)
这会返回'T',如图所示。