LISP条件句的特殊形式

LISP条件句的特殊形式,lisp,common-lisp,Lisp,Common Lisp,我正在读Peter Norvig的《人工智能编程的范例:Common 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

我正在读Peter Norvig的《人工智能编程的范例:Common 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
除非
,等等?

if
是一个通用条件,根据单个条件从两个分支中进行选择。当有两个以上的分支(
案例
)或只有一个分支(
时,
除非
)时,所有这些都是更简单的编写方法

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

如果
是一个通用条件,根据单个条件从两个分支中进行选择。当有两个以上的分支(
案例
)或只有一个分支(
时,
除非
)时,所有这些都是更简单的编写方法

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

这不仅是可能的,而且正是使用
cond
时发生的情况:

(宏扩展)(条件(V0)(打印“正片”)(1-(*2V)))
(t(打印“零”)0)
; ==>
(如果(v0)
(程序(打印“正片”)
(1-(*2V)))
(程序(打印“零”)
0))) 
因此,当您在CL中使用
cond
时,它会在宏扩展阶段将其替换为等效的
if
表单。这种情况通常在程序中使用宏的每个位置发生一次

通常,核心语言不支持多种方法来实现相同的功能,因此我想所有内容都将转换为
if
,除非实现找到保持其原始性的理由

表格的标题为“和”,反映了这一点

您可以定义自己的宏来执行条件,并且您可以自由选择现有的条件来替换它,因为宏将展开,直到没有更多的条件为止。以下是一个定义:

(defmacro aif(p a和可选c)
`(让((it,p))
(如果是,a,c)))
(宏扩展(aif)(非常昂贵的函数x)
(使用价值it)
(计算其他结果)
; ==>
(let((它(非常昂贵的函数x)))
(若有)
(使用价值it)
(计算其他结果)

这不仅是可能的,而且正是您使用
cond
时发生的情况:

(宏扩展)(条件(V0)(打印“正片”)(1-(*2V)))
(t(打印“零”)0)
; ==>
(如果(v0)
(程序(打印“正片”)
(1-(*2V)))
(程序(打印“零”)
0))) 
因此,当您在CL中使用
cond
时,它会在宏扩展阶段将其替换为等效的
if
表单。这种情况通常在程序中使用宏的每个位置发生一次

通常,核心语言不支持多种方法来实现相同的功能,因此我想所有内容都将转换为
if
,除非实现找到保持其原始性的理由

表格的标题为“和”,反映了这一点

您可以定义自己的宏来执行条件,并且您可以自由选择现有的条件来替换它,因为宏将展开,直到没有更多的条件为止。以下是一个定义:

(defmacro aif(p a和可选c)
`(让((it,p))
(如果是,a,c)))
(宏扩展(aif)(非常昂贵的函数x)
(使用价值it)
(计算其他结果)
; ==>
(let((它(非常昂贵的函数x)))
(若有)
(使用价值it)
(计算其他结果)

您位于PoAIP的第53页。如果你继续阅读本页和下一页,解释如下。

你在PoAIP的第53页。如果你继续阅读本页和下一页,解释如下。

你已经得到了答案,但是如果你想更多地阅读和/或练习,我建议你阅读中的章节
条件句。
。你已经得到了答案,但是如果你想更多地阅读和/或练习,我建议@ScottM中的
条件一章通过执行
(如果p1 c1 p2 c2 a)
修复,但是是的,其他条件都有优点,这就是为什么它们被用来代替
如果
@ScottM通过执行
(如果p1 c1 p2 c2 a)
修复的原因,其他条件也有优点,这就是它们被用来代替
if
的原因。