9mj*_*mjb 1 lisp eval common-lisp
如何在保持词汇背景的同时再次评估某些内容?
* (defvar form '(+ 1 2))
form
* form
(+ 1 2)
* (eval form) ;; This loses the lexical scope (not an issue here)
3
Run Code Online (Sandbox Code Playgroud)
有关需要词法范围的问题的示例
(let ((a 1) (b 2)
(form '(+ a b)))
(print form)
(print (eval form)) )
(+ a b)
The variable A is unbound.
Run Code Online (Sandbox Code Playgroud)
如何在同一个词法范围内两次评估该表格?
我想要多少次eval(在相同的词法范围内)?
与之前的问题相关 为什么SBCL eval函数会丢失它运行的宏?
我可能会弄错,但这似乎是一个XY问题.我想你的例子很简单,你的请求的原因已经消失了.你为什么需要这个?
不知道更多,我在想你可以用宏来解决这个问题:
(defun run (expr)
(funcall expr :run))
(defun src (expr)
(funcall expr :src))
(defmacro expr (&body rest)
`(let ((run (lambda () ,@rest))
(src ',@rest))
(lambda (m)
(case m
(:run (funcall run))
(otherwise src))))))
Run Code Online (Sandbox Code Playgroud)
您可以将其提供给它而不是引用您的代码expr,而是创建一个对象.这两个函数run并src获取此对象,并在原始词法环境中运行它(因为我创建了一个thunk)或返回表达式的源.你的例子将被写成:
(let* ((a 1)
(b 2)
(form (expr (+ a b))))
(print (src form))
(print (run form)))
Run Code Online (Sandbox Code Playgroud)
请注意,我改变了let,let*因为既不可用a也不b可用form.因此,您获得的词汇环境就像您运行代码代替expr表单一样.
Eval不使用一次也不使用两次.也许CLOS本来可以做得很好.