Common lisp 我是否混淆了宏观扩展和评估?

Common lisp 我是否混淆了宏观扩展和评估?,common-lisp,slime,Common Lisp,Slime,CLHS说,和是一个宏 因此,我对它的实现方式很感兴趣,并使用slime的slime macroexpand all-in-place来扩展(和1 2 nil 4 5),从而产生: (IF 1 (IF 2 (IF NIL (IF 4 (THE T 5) NIL) NIL) NIL) NIL) 我不明白的是,和应该在遇到nil值时立即停止

CLHS说,
是一个宏

因此,我对它的实现方式很感兴趣,并使用slime的
slime macroexpand all-in-place
来扩展
(和1 2 nil 4 5)
,从而产生:

(IF 1
    (IF 2
        (IF NIL
            (IF 4
                (THE T 5)
                NIL)
            NIL)
        NIL)
    NIL)
我不明白的是,
应该在遇到
nil
值时立即停止计算。但是在这里,
正在超越
…(如果没有…

我是否混淆了宏观扩展和评估


我还试图用
C-C-t
但是slime(或sbcl)来追踪
(和12 nil 4 5)
的评估抱怨:
无法使用封装来跟踪扩展代码中的匿名函数#

,当任何谓词求值为
nil
时,它会转到另一个选项,即
nil
,而不求值更多谓词。在您的示例中,
4
5
从未求值。您是对的。
4
5
只是第三个
if
的then子句的一部分。我只是感到困惑,因为我希望
(如果是NIL,那就没有意义了。谢谢。所以从性能的角度来看:即使它不需要计算更多的谓词——因为嵌套结构,它仍然需要将
NIL
传播两次,不是吗?不。如果
1
是真的(事实就是这样)它从未计算过的else子句。因此,只有
if
的else子句中的
nil
被计算为false,并且整个嵌套
if
表单的结果被计算。就计算而言,它计算
1
2
nil
nil
(最后一个是结果)。我明白了,好的,谢谢。一个合理的编译器会消除“if nil”部分之后所有不可访问的代码。但是宏扩展与该级别无关,只与生成代码有关。