为什么这个 Common Lisp 宏不起作用?书上的答案sheet错了吗?
Why this Common Lisp macro does not work? Is the answer sheet from the book wrong?
我正在尝试通过 Common Lisp:对符号计算的简单介绍 来学习 Common Lisp。此外,我正在使用 SBCL、Emacs 和 Slime。
在第14章的最后一章中,作者介绍了宏。出现以下问题:
Write a macro called VARIABLE-CHAIN
that accepts any number of
inputs. The expression (VARIABLE-CHAIN A B C D)
should expand into an
expression that sets A
to ’B
, B
to ’C
, and C
to ’D
.
答案sheet是:
从 pdf 复制并粘贴到此处:
(defmacro variable-chain (&rest vars)
‘(progn
,@(do ((v vars (rest v))
(res nil))
((null (rest v)) (reverse res))
(push ‘(setf ,(first v) ’,(second v))
res))))
在 Emacs 中,我使用这个 hack 来删除弯引号。将它粘贴到 Emacs 中,我得到:
(defmacro variable-chain (&rest vars)
'(progn
,@(do ((v vars (rest v))
(res nil))
((null (rest v)) (reverse res))
(push '(setf ,(first v)
',(second v))
res))))
不幸的是,我无法将它编译成史莱姆的REPL,它抛出一个错误:
> READ error during COMPILE-FILE: Comma not inside a backquote.
我尝试将 '(progn
更改为:
`(progn
但它也不起作用:"comma not inside a backquote"
。
我是不是做错了什么?或者,答案 sheet 不正确?
谢谢。
您还需要更改另一个:
(defmacro variable-chain (&rest vars)
`(progn
;; this one you did change
,@(do ((v vars (rest v))
(res nil))
((null (rest v)) (reverse res))
(push `(setf ,(first v)
;; ^^^ also need to change this one
',(second v))
res))))
‘
是反引号,而 ’
是常规引号,但是您的“hack”错误地将它们都变成了常规引号 '
字符:
(defmacro variable-chain (&rest vars)
‘(progn
;; backquote
,@(do ((v vars (rest v))
(res nil))
((null (rest v)) (reverse res))
(push ‘(setf ,(first v) ’,(second v))
;; backquote quote
res))))
我正在尝试通过 Common Lisp:对符号计算的简单介绍 来学习 Common Lisp。此外,我正在使用 SBCL、Emacs 和 Slime。
在第14章的最后一章中,作者介绍了宏。出现以下问题:
Write a macro called
VARIABLE-CHAIN
that accepts any number of inputs. The expression(VARIABLE-CHAIN A B C D)
should expand into an expression that setsA
to’B
,B
to’C
, andC
to’D
.
答案sheet是:
从 pdf 复制并粘贴到此处:
(defmacro variable-chain (&rest vars)
‘(progn
,@(do ((v vars (rest v))
(res nil))
((null (rest v)) (reverse res))
(push ‘(setf ,(first v) ’,(second v))
res))))
在 Emacs 中,我使用这个 hack 来删除弯引号。将它粘贴到 Emacs 中,我得到:
(defmacro variable-chain (&rest vars)
'(progn
,@(do ((v vars (rest v))
(res nil))
((null (rest v)) (reverse res))
(push '(setf ,(first v)
',(second v))
res))))
不幸的是,我无法将它编译成史莱姆的REPL,它抛出一个错误:
> READ error during COMPILE-FILE: Comma not inside a backquote.
我尝试将 '(progn
更改为:
`(progn
但它也不起作用:"comma not inside a backquote"
。
我是不是做错了什么?或者,答案 sheet 不正确?
谢谢。
您还需要更改另一个:
(defmacro variable-chain (&rest vars)
`(progn
;; this one you did change
,@(do ((v vars (rest v))
(res nil))
((null (rest v)) (reverse res))
(push `(setf ,(first v)
;; ^^^ also need to change this one
',(second v))
res))))
‘
是反引号,而 ’
是常规引号,但是您的“hack”错误地将它们都变成了常规引号 '
字符:
(defmacro variable-chain (&rest vars)
‘(progn
;; backquote
,@(do ((v vars (rest v))
(res nil))
((null (rest v)) (reverse res))
(push ‘(setf ,(first v) ’,(second v))
;; backquote quote
res))))