LISP条件的特殊表格

时间:2016-03-21 05:40:41

标签: lisp common-lisp

我正在读Peter Norvig所着的“人工智能编程范例:共同LISP中的案例研究”,在关于条件特殊形式的章节中,它说它们都可以被替换为如果表格

(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表单创建一个宏函数来替换whenunlessand等等吗?

3 个答案:

答案 0 :(得分:8)

IF是一个通用条件,根据单个条件从两个分支中选择。当有两个以上的分支(ANDORCASE)或只有一个分支(WHEN,{{1}时,所有这些都是更简单的方法来编写它}})。

UNLESS也可以使用COND完成,例如:

IF

答案 1 :(得分:5)

这不仅是可能的,而且恰恰是您使用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将表单标题反映为“Special Operator IF”和“Macro COND”。

您可以定义自己的宏来执行条件,并且可以自由选择已经可用的条件来替换它,因为宏已经扩展,直到不再有左边。以下是anaphoric if的定义:

(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)))

答案 2 :(得分:1)

您在PoAIP的第53页。如果您继续阅读本页和下一页,则说明如下。