3
我已經定義了下面的宏:如何界定懶惰和
(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'。
我認爲代碼看起來不友好。我會建議擺脫APPEND,創建一個謂詞來檢測基於arglist的方法存在,併爲代碼編寫生成器函數。使用「功能抽象」。 – 2013-04-05 08:04:55
謝謝!我會仔細研究一下,特別是因爲我更經常需要這個功能。 – 2013-04-05 12:08:02