macros - 为什么 SBCL eval 函数会丢失它运行的 macrolet?

标签 macros lisp eval common-lisp sbcl

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

(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 内部),它就会工作!

(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

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

!就是这样。我将这两个 macrolet 宏定义为 defmacros,然后 eval 起作用了!

为什么?! Eval 正在失去 macrolet。 (我是 macrolet 的新手,没有 lisp 天才)
或者,我如何在没有评估的情况下执行此操作?
任何关于我的代码的一般注释也很好。这太复杂了吗?
此外,宏中的错误似乎会出现尴尬的错误消息。有什么帮助吗?

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

最佳答案

EVAL在 Common Lisp 中,仅在当前动态环境和空词法环境中求值。将它包含在 MACROLETLET 等词法结构中......或类似的是行不通的。

关于macros - 为什么 SBCL eval 函数会丢失它运行的 macrolet?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17483503/

相关文章:

c# - 评估日期仅显示天数

php - 此代码中的 eval() 为何不安全?

c++ - #define 数组索引不起作用

c - 将任意数量的参数传递给函数

vba - 在 Excel 中跟踪 Share-drive 用户名和打开时间?

ms-access - 运行宏/查询后 MS Access 取消选择列表框

list - LISP 比较板中的元素

c# - LINQ to SQL 是否可以使用其他语言?

c# - 在 ASP.NET 中使用 ItemTemplate 参数执行方法

lisp - SICP 2.42 八皇后。帮忙看看我的代码有什么问题?