为什么SBCL eval函数会丢失它运行的宏?

9mj*_*mjb 3 lisp macros eval sbcl common-lisp

(打印x)打印出我想要的eval,但是(eval x)失败,但如果我运行x它就可以了!我错过了什么?
请告诉我为什么这不起作用,或者我做了一些愚蠢的事情.
我正在尝试打印动态大小的表并设置lambda变量,以最终评估表中每个单元格的表达式.
顺便说一句我弄清楚为什么eval失败了.(eval x)正在丢失宏,但是为什么?!
这有效:

(defvar varlist '(a b c d))
(defvar vvars   '(c d))
(defvar hvars   '(a b))
(macrolet ((AlternateVariable (var &rest body)
               `(dolist (,var '(nil t)) ,@body))
           (AlternateVariables (varlist &rest body)
               (if (null varlist)
                   (cons 'progn body)
                   `(AlternateVariable  ,(car varlist)
                    (AlternateVariables ,(cdr varlist) ,@body)))))
      (let ((listvarlist (cons 'list varlist)))
        (print
         `(AlternateVariables ,(reverse vvars)
            (AlternateVariables ,(reverse hvars)
              (format t "row=~S~%" ,listvarlist) ))))
      nil)
Run Code Online (Sandbox Code Playgroud)

它打印出我想要的东西:

(alternatevariables (d c)
 (alternatevariables (b a) (format t "row=~S~%" (list a b c d)))) 
Run Code Online (Sandbox Code Playgroud)

如果我将"打印"更改为"eval",我会得到

; in: alternatevariables (d c)
;     (B A)
; caught warning:
;   undefined variable: a
Run Code Online (Sandbox Code Playgroud)

但是如果我运行它打印的内容(在macrolet内部)就可以了!

(macrolet ((AlternateVariable (var &rest body)
               `(dolist (,var '(nil t)) ,@body))
           (AlternateVariables (varlist &rest body)
               (if (null varlist)
                   (cons 'progn body)
                   `(AlternateVariable  ,(car varlist)
                    (AlternateVariables ,(cdr varlist) ,@body)))))
  (alternatevariables (d c)
    (alternatevariables (b a) (format t "row=~S~%" (list a b c d))))
  nil)
Run Code Online (Sandbox Code Playgroud)

它打印出来

row=(nil nil nil nil)
row=(t nil nil nil)
row=(nil t nil nil)
row=(t t nil nil)
row=(nil nil t nil)
row=(t nil t nil)
row=(nil t t nil)
row=(t t t nil)
row=(nil nil nil t)
row=(t nil nil t)
row=(nil t nil t)
row=(t t nil t)
row=(nil nil t t)
row=(t nil t t)
row=(nil t t t)
row=(t t t t)
nil
Run Code Online (Sandbox Code Playgroud)

我听说"eval是邪恶的",但我需要反引用来获得正确的评估顺序并评估一些参数而不是其他参数.打印是一个很好的调试工具,但后来我错过了eval的东西.eval会丢失宏吗?

!而已.我将这两个宏宏定义为defmacros然后eval工作!

为什么?!Eval正在失去宏.(我是Macrolet的新手,没有lisp天才)
或者,如果没有eval,我该怎么办呢?
关于我的代码的任何一般注释也会很好.这太复杂了吗?
此外,宏中的错误似乎得到尴尬的错误消息.对此有何帮助?

$ sbcl
这是SBCL 1.1.2-1.fc18,ANSI Common Lisp的一个实现.

Rai*_*wig 5

Common Lisp中的EVAL仅在当前动态环境和null词法环境中进行评估.封闭它的词汇结构,如MACROLET,LET...或类似的是行不通的.