如何在lisp中求值两次(不使用求值)

如何在lisp中求值两次(不使用求值),lisp,common-lisp,eval,Lisp,Common Lisp,Eval,我如何在保持词汇上下文的同时再次评估某个单词 * (defvar form '(+ 1 2)) form * form (+ 1 2) * (eval form) ;; This loses the lexical scope (not an issue here) 3 例如,需要词法范围的问题 (let ((a 1) (b 2) (form '(+ a b))) (print form) (print (eval form)) ) (+ a b) The variab

我如何在保持词汇上下文的同时再次评估某个单词

* (defvar form '(+ 1 2))
form
* form
(+ 1 2)
* (eval form) ;; This loses the lexical scope (not an issue here)
3
例如,需要词法范围的问题

(let ((a 1) (b 2)
      (form '(+ a b)))
  (print form)
  (print (eval form))  )
(+ a b) 
The variable A is unbound.
我如何在同一词汇范围内两次评估该形式?
如何评估我想要的次数(在同一词汇范围内)

与前面的问题有关

不能使用eval在词法范围内对表单求值。引用评估的HyperSpec页面(重点添加):

语法: 评估格式和右箭头;结果*

参数和值:
  • 形式——形式
  • 结果通过表格评估得出的值
说明: 在当前动态环境和空词汇表中计算表单 环境

环境支持中的评估实现 尽管标准
eval
不允许您指定词法环境,但某些实现可能以实现定义的方式提供此功能。比如说

CLISP的
ext:eval env
函数(外部:EVAL-ENV表单和可选环境)。对窗体求值 在给定的词汇环境中,就好像形式是 环境来自的程序


不能使用eval在词法范围内对表单进行求值。引用评估的HyperSpec页面(重点添加):

语法: 评估格式和右箭头;结果*

参数和值:
  • 形式——形式
  • 结果通过表格评估得出的值
说明: 在当前动态环境和空词汇表中计算表单 环境

环境支持中的评估实现 尽管标准
eval
不允许您指定词法环境,但某些实现可能以实现定义的方式提供此功能。比如说

CLISP的
ext:eval env
函数(外部:EVAL-ENV表单和可选环境)。对窗体求值 在给定的词汇环境中,就好像形式是 环境来自的程序


我可能弄错了,但这似乎是个错误。我猜你的例子太简单了,你提出要求的理由已经不存在了。你为什么需要这个

在不了解更多信息的情况下,我认为您可以使用宏解决此问题:

(卸载运行(expr)
(funcall expr:run))
(除src(expr)
(funcall expr:src))
(defmacro expr和车身支撑)
`(let((run(lambda(),@rest))
(src',@rest))
(λ(m)
(案例m)
(:运行(funcall运行))
(否则src(()())))
您将代码输入到
expr
并创建一个对象,而不是引用代码。两个函数
run
src
获取这个对象,或者在原始词汇环境中运行它(因为我创建了thunk),或者返回表达式的源代码。你的例子可以写成:

(let*((a1)
(b 2)
(表格(expr(+AB)))
(打印(src表格))
(打印(运行表单)))
注意,我从
let
更改为
let*
,因为
a
b
都不适用于
表单
。因此,您得到的词法环境与您运行代码来代替
expr
表单的情况相同


Eval不使用一次或两次。也许
CLOS
也能起到同样好的作用。

我可能弄错了,但这似乎是一个错误。我猜你的例子太简单了,你提出要求的理由已经不存在了。你为什么需要这个

在不了解更多信息的情况下,我认为您可以使用宏解决此问题:

(卸载运行(expr)
(funcall expr:run))
(除src(expr)
(funcall expr:src))
(defmacro expr和车身支撑)
`(let((run(lambda(),@rest))
(src',@rest))
(λ(m)
(案例m)
(:运行(funcall运行))
(否则src(()())))
您将代码输入到
expr
并创建一个对象,而不是引用代码。两个函数
run
src
获取这个对象,或者在原始词汇环境中运行它(因为我创建了thunk),或者返回表达式的源代码。你的例子可以写成:

(let*((a1)
(b 2)
(表格(expr(+AB)))
(打印(src表格))
(打印(运行表单)))
注意,我从
let
更改为
let*
,因为
a
b
都不适用于
表单
。因此,您得到的词法环境与您运行代码来代替
expr
表单的情况相同


Eval不使用一次或两次。也许
CLOS
也可以很好地工作。

是的,这是我的问题:如何在lisp中计算两次(不使用eval)。我知道我不能使用eval,但是关于某种宏、apply或funcall技巧呢。。。还是你在告诉我这是不可能的。。我知道这不是不可能的,只是它有多尴尬的问题。我理解你在词汇环境中评估的意思。你不能那样做。我不知道你说的“评估两次”是什么意思。你可以这样做,例如,
(eval(eval)(list'+12))
和两次真正意义上的eval,但我怀疑这就是你的意思。除错器之外,没有函数可以调用,可以访问词法变量的值,给定它的名称。Xach——这是我一直在寻找(但不知道)的答案的很大一部分。让(表格’(+AB))(让((A1)(B2))(申请(car表格)(cdr表格)))。。但是在那一点上没有办法评估a和b。。。这个答案(eval使用空的词法环境)并没有真正解决我的问题(而且似乎没有办法解决这个问题…几乎就像词法环境一样)