3

(print x) 打印出我想要评估的内容,但是 (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)

它打印出我想要的内容:

(alternatevariables (d c)
 (alternatevariables (b a) (format t "row=~S~%" (list a b c d)))) 

如果我将“打印”更改为“评估”,我会得到

; in: alternatevariables (d c)
;     (B A)
; caught warning:
;   undefined variable: a

但是如果我运行它打印的内容(在宏内)它就可以工作!

(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)

它打印

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

我听说过“评估是邪恶的”,但我需要反引号来获得正确的评估顺序并评估一些论点而不是其他论点。Print 是一个很好的调试工具,但是我在 eval 中遗漏了一些东西。eval 会丢失宏吗?

!就是这样。我将这两个宏定义为 defmacros 然后 eval 工作!

为什么?!Eval 正在失去宏。(我是 macrolet 的新手,没有 lisp 天才)
或者,我如何在没有 eval 的情况下做到这一点?
关于我的代码的任何一般性注释也会很好。这是否过于复杂?
此外,宏中的错误似乎会收到尴尬的错误消息。有什么帮助吗?

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

4

1 回答 1

5

Common Lisp 中的EVAL仅在当前动态环境和空词法环境中计算。MACROLET将它包含在, , ... 或类似的词汇结构中LET是行不通的。

于 2013-07-05T07:48:32.820 回答