为什么这个 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))))