为什么SBCL eval函数会丢失正在运行的宏? [英] Why does SBCL eval function lose the macrolet it's running in?

查看:104
本文介绍了为什么SBCL eval函数会丢失正在运行的宏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(print x)精确打印我要评估的内容,但是(eval x)失败, 但是,如果我运行x,它将起作用!我想念什么?
请告诉我为什么这不起作用,或者我是否在做一些愚蠢的事情.
我正尝试打印一张动态尺寸的表格并设置lambda变量,以便最终为表格中的每个单元格计算一个表达式.
顺便说一句,我想出了为什么评估失败. (eval x)失去了宏,但为什么呢?
这有效:

(print x) prints exactly what I want to eval, but (eval x) fails, but if I run x it works! What am I missing?
Please tell me why this doesn't work, or if I'm doing something stupid.
I'm trying to print a table of dynamic size and setting lambda variables to eventually evaluate an expression for each cell in the table.
BTW I figured out why eval fails. (eval x) is losing the macrolet, but WHY?!
This works:

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

并打印出我想要的内容:

and it prints what I want it to:

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

如果我将打印"更改为评估",我将得到

If I change that "print" to "eval" I get

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

但是,如果我运行它打印的内容(在宏内),它将起作用!

but if I run what it printed (inside the macrolet) it works!

(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. eval会丢失宏吗?

!而已.我将这两个宏宏定义为defmacros,然后进行评估!

为什么? Eval正在失去该宏. (我是Macrolet的新手,没有天才的天才)
或者,如何在不进行评估的情况下做到这一点?
关于我的代码的任何一般注释也将很好.这太复杂了吗?
此外,宏中的错误似乎还会出现尴尬的错误消息.有什么帮助吗?

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

I have heard "eval is evil" but I need the backquote to get the right evaluation order and evaluate some arguments but not others. Print is a good debug tool, but then I'm missing something with eval. Does eval lose the macrolet?

! That's it. I defined those two macrolet macros as defmacros and then eval works!

Why?! Eval is losing the macrolet. (I'm new to macrolet and no lisp genius)
Or, how do I do this without eval?
Any general notes on my code would be nice too. Is this over complicated?
Also, errors in macros seem to get awkward error messages. Any help with that?

$ sbcl
This is SBCL 1.1.2-1.fc18, an implementation of ANSI Common Lisp.

推荐答案

EVAL 仅在当前动态环境和空词法环境中求值.将其包含在MACROLETLET,...或类似的词法构造中将无法正常工作.

EVAL in Common Lisp only evaluates in a current dynamic environment and the null lexical environment. Enclosing it in lexical constructs like MACROLET, LET, ... or similar is not going to work.

这篇关于为什么SBCL eval函数会丢失正在运行的宏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆