微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么 with-gensyms 的这种实现会生成一个额外的逗号?

如何解决为什么 with-gensyms 的这种实现会生成一个额外的逗号?

以下 with-gensyms 实现,旨在对类似 let 的参数列表进行操作,在嵌套的 let 中生成一个额外的逗号:

(defmacro with-gensyms (vars &rest forms)
  `(let,(loop for var in vars
          collect (if (listp var)
                      `(,(car var) (gensym))
                      `(,var (gensym))))
     `(let,(loop for genvar in vars
              collect (if (listp genvar)
                          `(,(car genvar),(car (cdr genvar)))
                          `(,genvar nil))),@forms)))

宏展开示例:

(with-gensyms ((var1 1) (var2 2) (testvar "testname") the-number-zero))

(LET ((VAR1 (GENSYM))
      (VAR2 (GENSYM))
      (TEStvar (GENSYM))
      (THE-NUMBER-ZERO (GENSYM)))
  `(LET,((VAR1 1) (VAR2 2) (TEStvar "testname") (THE-NUMBER-ZERO NIL))))

在嵌套 let 的参数列表之前有一个额外的逗号,我不清楚为什么会这样。

目标输出如下:

(let ((var1 (gensym)) (var2 (gensym)) (testvar (gensym)) (the-number-zero (gensym)))
  `(let ((,var1 1) (,var2 2) (,testvar "testname") (,the-number-zero nil))))

任何帮助都会很好!

解决方法

这值得更好的解释,而不仅仅是一个注释。有些人可能会对此感到困惑。您必须跟踪哪些括号已打开,哪些已关闭。将任何不靠在同一行上的括号对排列起来,这样更容易解释。

(defmacro with-gensyms (vars &rest forms)

;; v-- this backticked-parenthesis has been opened here.

  `(let,(loop for var in vars
          collect (if (listp var)
                      `(,(car var) (gensym))
                      `(,var (gensym))
                  )
         )

;; ^-- but it hasn't been closed yet.
;;      so we now have to unquote for that one...
;;   v-- as well as this new one.

     `(let,(loop for genvar in vars
              collect (if (listp genvar)
                          `(,(car genvar),(car (cdr genvar)))
                          `(,genvar nil)
                      )
             ),@forms

      )  ;;  second backtick closes here.

   )  ;;  first backtick closes here.

)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。