我正在阅读Peter的“人工智能编程的范例:通用LISP的案例研究”,在关于条件词的特殊形式的章节中,书中说它们都可以被if形式所取代。
(when test a b c) == (if test (progn a b c))
(unless test x y) == (if (not test) (progn x y)
(and a b c) == (if a (if b c))
(or a b c) == (if a a (if b b c))
(case a (b c) (t x)) == (if (eql a 'b) c x) 我不知道这是怎么回事,有人能给我解释一下吗?那么cond表单呢,它也可以替换为if表单吗?然后,我可以用if表单创建一个宏函数来替换when、unless、and等.?
发布于 2016-03-21 06:05:07
IF是一个通用条件,它根据单个条件从两个分支中进行选择。当有两个以上的分支(AND、OR、CASE)或只有一个分支(WHEN、UNLESS)时,所有这些都是编写它的更简单的方法。
COND也可以使用IF完成,例如:
(eval-when (:compile-toplevel :load-toplevel :execute)
(defun ifify-clauses (clauses)
(when clauses
(destructuring-bind (condition form) (first clauses)
`(if ,condition ,form ,(ifify-clauses (rest clauses)))))))
(defmacro if-cond (&body clauses)
(ifify-clauses clauses))
(macroexpand '(if-cond
((= 3 1) "foo")
((= 3 2) "bar")
((= 3 3) "quux")))
;=> (IF (= 3 1)
; "foo"
; (IF (= 3 2)
; "bar"
; (IF (= 3 3)
; "quux"
; NIL)))发布于 2016-03-21 13:31:07
这不仅是可能的,而且是使用cond时发生的事情。
(macroexpand '(cond ((< v 0) (print "negative") (* -2 v))
((> v 0) (print "positive") (1- (* 2 v)))
(t (print "zero") 0)))
; ==>
(if (< v 0)
(progn (print "negative")
(* -2 v))
(if (> v 0)
(progn (print "positive")
(1- (* 2 v)))
(progn (print "zero")
0))) 因此,当您在CL中使用cond时,它在宏展开阶段用等效的if表单替换它。这种情况通常在程序中使用宏的每个地方发生一次。
通常,核心语言不支持很多方法来做到这一点,所以我想所有的东西都会被转换成if,除非实现找到了保持原语的理由。
CLHS通过表单的标题"IF“和"COND”来反映这一点。
您可以定义自己的宏来执行条件,并且您可以自由地选择已经可用的条件来替换它,因为宏是展开的,直到没有剩下的条件为止。以下是回指的定义
(defmacro aif (p a &optional c)
`(let ((it ,p))
(if it ,a ,c)))
(macroexpand '(aif (extremely-expensive-function x)
(use-value it)
(compute-other-result)))
; ==>
(let ((it (extremely-expensive-function x)))
(if it
(use-value it)
(compute-other-result)))发布于 2016-03-21 16:44:19
你在PoAIP的第53页。如果你继续阅读这一页和下一页,解释如下。
https://stackoverflow.com/questions/36123901
复制相似问题