次のマクロを定義しました。
(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」を簡潔に定義することができません。