为什么在我的环境中编译 Common Lisp 宏会产生与书中不同的结果?有可能达到同样的目的吗?
Why does the compilation of a Common Lisp macro in my environment produce a different result from the book? Is it possible to achieve the same?
我正在尝试通过 Common Lisp:对符号计算的简单介绍 来学习 Common Lisp。此外,我正在使用 SBCL、Emacs 和 Slime。
在第14章的最后一章中,作者介绍了宏。在关于编译它的一节中,他提到:
Since macro expansion can happen at any time, you should not write
macros that produce side effects, such as assignments or i/o. But it’s
fine for the macro to expand into an expression that produces side
effects.
作为说明错误宏的一种方式,他提供了以下示例:
(defmacro bad-announce-macro ()
(format t "~%Hi mom!"))
(defun say-hi ()
(bad-announce-macro))
> (compile ’say-hi)
Hi, mom!
SAY-HI
> (say-hi)
NIL
当我尝试在我的环境中模仿相同的东西时,我有一个 不同的 输出:
CL-USER> (defmacro bad-announce-macro ()
(format t "~%Hi mom!"))
BAD-ANNOUNCE-MACRO
CL-USER> (bad-announce-macro)
Hi mom!
NIL
CL-USER> (defun say-hi ()
(bad-announce-macro))
Hi mom!
SAY-HI
CL-USER> (say-hi)
NIL
CL-USER> (compile (say-hi))
; Evaluation aborted on #<UNDEFINED-FUNCTION NIL {100408C143}>.
CL-USER> (compile 'say-hi)
SAY-HI
NIL
NIL
CL-USER> (compile `say-hi)
SAY-HI
NIL
NIL
如您所见,在编译函数时,缺少 Hi mom!
部分。
为什么会这样?这仅仅是因为 Lisp 实现的差异吗?
是否可以实现相同的输出?
我认为情况并非如此,但我会放一个书中的打印屏幕,以防这与从 pdf 复制并粘贴到 Emacs Slime 的 REPL 中有关。
SBCL 默认已经编译了 REPL 中的定义。在已编译的函数上调用 compile
然后可能什么都不做。
执行 defun
表单时,已经打印了 Hi, mom!
消息。请参阅上面的示例。
Touretzky 在他的书中使用了不同的实现,它在 REPL 中使用了解释器。然后,编译器将由用户通过调用 compile
、compile-file
或类似的方式调用。
我正在尝试通过 Common Lisp:对符号计算的简单介绍 来学习 Common Lisp。此外,我正在使用 SBCL、Emacs 和 Slime。
在第14章的最后一章中,作者介绍了宏。在关于编译它的一节中,他提到:
Since macro expansion can happen at any time, you should not write macros that produce side effects, such as assignments or i/o. But it’s fine for the macro to expand into an expression that produces side effects.
作为说明错误宏的一种方式,他提供了以下示例:
(defmacro bad-announce-macro ()
(format t "~%Hi mom!"))
(defun say-hi ()
(bad-announce-macro))
> (compile ’say-hi)
Hi, mom!
SAY-HI
> (say-hi)
NIL
当我尝试在我的环境中模仿相同的东西时,我有一个 不同的 输出:
CL-USER> (defmacro bad-announce-macro ()
(format t "~%Hi mom!"))
BAD-ANNOUNCE-MACRO
CL-USER> (bad-announce-macro)
Hi mom!
NIL
CL-USER> (defun say-hi ()
(bad-announce-macro))
Hi mom!
SAY-HI
CL-USER> (say-hi)
NIL
CL-USER> (compile (say-hi))
; Evaluation aborted on #<UNDEFINED-FUNCTION NIL {100408C143}>.
CL-USER> (compile 'say-hi)
SAY-HI
NIL
NIL
CL-USER> (compile `say-hi)
SAY-HI
NIL
NIL
如您所见,在编译函数时,缺少 Hi mom!
部分。
为什么会这样?这仅仅是因为 Lisp 实现的差异吗? 是否可以实现相同的输出?
我认为情况并非如此,但我会放一个书中的打印屏幕,以防这与从 pdf 复制并粘贴到 Emacs Slime 的 REPL 中有关。
SBCL 默认已经编译了 REPL 中的定义。在已编译的函数上调用 compile
然后可能什么都不做。
执行 defun
表单时,已经打印了 Hi, mom!
消息。请参阅上面的示例。
Touretzky 在他的书中使用了不同的实现,它在 REPL 中使用了解释器。然后,编译器将由用户通过调用 compile
、compile-file
或类似的方式调用。