Lisp 从s表达式创建lambda
我有一个s表达式绑定到Common Lisp中的一个变量:Lisp 从s表达式创建lambda,lisp,lambda,eval,common-lisp,closures,Lisp,Lambda,Eval,Common Lisp,Closures,我有一个s表达式绑定到Common Lisp中的一个变量: (defvar x '(+ a 2)) 现在,我想创建一个函数,在调用该函数时,在定义表达式的范围内对其求值。我试过这个: (let ((a 4)) (lambda () (eval x))) 及 但这两个都会产生一个问题:EVAL将在顶层对代码求值,因此我无法捕获表达式中包含的变量。请注意,我不能将LET表单放入EVAL中。有什么解决办法吗 编辑:那么,如果没有解决评估问题的方法,还有什么方法可以做到呢 编辑:有一个关于我到底
(defvar x '(+ a 2))
现在,我想创建一个函数,在调用该函数时,在定义表达式的范围内对其求值。我试过这个:
(let ((a 4))
(lambda () (eval x)))
及
但这两个都会产生一个问题:EVAL将在顶层对代码求值,因此我无法捕获表达式中包含的变量。请注意,我不能将LET表单放入EVAL中。有什么解决办法吗
编辑:那么,如果没有解决评估问题的方法,还有什么方法可以做到呢
编辑:有一个关于我到底想做什么的问题。我正在写一个编译器。我想接受在定义表达式的词法环境中变量闭合的s表达式。将其编写为宏可能确实更好。CLISP实现了一个扩展,用于在词汇环境中计算表单。从它是一个扩展的事实来看,我怀疑您不能以标准兼容的方式来实现这一点
(ext:eval-env x (ext:the-environment))
请参阅。在Common Lisp中,您可以定义允许您将环境传递给
(eval…
)的选项<代码>*evalhook*与平台无关。您想要解决的实际问题是什么?最有可能的是,你试图以错误的方式解决它。词法绑定用于在其范围内以词法形式出现的内容,而不是用于从外部获得的随机内容
也许你想要一个动态的结束?虽然在一些Lisp方言中(据我所知,像Pico Lisp)存在这种情况,但在Common Lisp中并不存在这种情况
请注意,您可以执行以下类似操作:
(defvar *a*)
(defvar *x* '(+ *a* 2)) ;'
(let ((a 10))
;; ...
(let ((*a* a))
(eval *x*)))
不过,我建议您仔细考虑是否真的需要它。您需要创建具有必要绑定的代码。在代码周围包装一个LET,并绑定您希望在代码中可用的每个变量:
(defvar *x* '(+ a 2))
(let ((a 4))
(eval `(let ((a ,a))
,*x*)))
可以使用COMPILE将表达式编译为函数,然后使用PROGV在动态设置变量的环境中对所有编译后的函数进行funcy。或者,更好的方法是使用COMPILE将表达式编译成接受变量的函数 Compile将函数定义作为列表接受,并将其转换为函数。对于SBCL,此函数将编译为机器代码,并将高效执行 第一个选项(使用compile和progv): 第二种选择:
(defvar *fn* (compile nil '(lambda (a) (+ a 2))))
(funcall *fn* 4)
=>
6
你从哪里得到内部表达式?除非您是从外部源读取,否则可以尝试使用宏而不是eval。我是从外部源读取的。非常正确,它们似乎已被ANSI删除
(defvar *fn* (compile nil '(lambda () (+ a 2)))
(progv '(a) '(4) (funcall *fn*))
=>
6
(defvar *fn* (compile nil '(lambda (a) (+ a 2))))
(funcall *fn* 4)
=>
6