Common lisp 我是否混淆了宏观扩展和评估?
CLHS说,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值时立即停止
和
是一个宏
因此,我对它的实现方式很感兴趣,并使用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”部分之后所有不可访问的代码。但是宏扩展与该级别无关,只与生成代码有关。