(LIST。VALUES)不是正确的列表

时间:2018-10-13 19:34:07

标签: common-lisp

这是示例代码:

(defun my-test (&rest values)
  (macrolet ((my-macro (v)
               `(list ,@v)))
    (print values)
    (my-macro values)))

(my-test 1 2 3 4)
;; The goal is to obtain : (1 2 3 4).

当我执行最后一行时,它会显示(1 2 3 4),然后函数将失败。 当我执行defun或尝试执行最后一行时,我得到以下警告/错误(分别):

; in: DEFUN MY-TEST
;     (MY-PACKAGE::MY-MACRO VALUES)
; ==>
;   (LIST . VALUES)
; 
; caught ERROR:
;   (LIST . VALUES) is not a proper list.
; 
; compilation unit finished
;   caught 1 ERROR condition

为什么会失败?

1 个答案:

答案 0 :(得分:4)

宏转换代码,它对运行时值一无所知,只有文字代码。例如。

(cond (p1 e1) (p2 e2) (t e3))

变成

(if p1
    e1
    (if p2
        e3))

我们真的不知道p1在这一刻。现在看一下您的代码:

(defun my-test (&rest values)
  (macrolet ((my-macro (v)
               `(list ,@v)))
    (print values)
    (my-macro values)))

因此,在创建my-test时会扩展宏。如果不能my-macro,请问我如何(my-macro values)扩展(list . values)(list . values)无效的Common Lisp,这是错误的根源。

您也许应该在没有宏的情况下执行此操作。例如。只需使用values即可正常工作。要使用列表作为参数调用函数,可以使用apply。要复制不需要的列表,可以使用copy-listcopy-tree