在Lisp中,如何获取表达式的值?

在Lisp中,如何获取表达式的值?,lisp,Lisp,这将打印数据,但我希望它打印显示。我想打印值,而不是表达式,我该怎么做 (defun display (x) (list x)) (setq temp 'data) (set temp 'show) (display 'data) 如果你不知道这个变量是否有界呢?我必须编写一个函数,它接受一个键和一个值,如果键不存在,那么我必须执行setq key value,如果键已经存在,那么我将向键添加值。在这种情况下,如果我这样做(storedata键值),如果值没有被绑定,我会得到一个未绑定的

这将打印
数据
,但我希望它打印
显示
。我想打印值,而不是表达式,我该怎么做

(defun display (x)
  (list x))

(setq temp 'data)
(set temp 'show)
(display 'data)
如果你不知道这个变量是否有界呢?我必须编写一个函数,它接受一个键和一个值,如果键不存在,那么我必须执行setq key value,如果键已经存在,那么我将向键添加值。在这种情况下,如果我这样做(storedata键值),如果值没有被绑定,我会得到一个未绑定的错误,我将如何处理这种情况


例如,如果没有mydata,而我有(storedata值mydata),则mydata将变成(值),现在如果我有(storedata值2 mydata),则mydata将变成(值2)

在Lisp中用
引用列表或符号
完全等同于使用特殊形式
(quote…
)。它专门用于使引用的内容不被评估数据或键入REPL中的数据与
(quote data)
相同,计算结果为符号
数据

不带引号的
data
计算为当前范围内变量
data
的值。因此,在REPL:

[1]> (setq data 14)
14
[2]> data
14
第一个表达式的计算结果也是
14
,因为
setq
返回绑定变量的值(在这方面,其作用类似于C中的赋值运算符
=

在上述代码中,您所做的是将名为
temp
的变量设置为包含符号
data
,然后使用
set
(不带
setq
)将名为
data
的变量设置为符号
show
。这有点类似于在Perl中使用软引用(例如),但我不认为它作为Lisp技术得到特别广泛的应用或建议


顺便说一下,您的
display
过程可能也没有按照您的想法执行:它返回一个包含您传递给它的任何内容的元素列表。在REPL中键入值时会打印该值,这是因为任何表达式的值都会在REPL中打印。要在程序中显示值,可以使用
print
,也可以使用。(我假设您使用的是Common Lisp,因为它显然不是Scheme,但可能是其他一些Lisp变体,在这种情况下,该链接将不会有帮助。)

在Lisp中使用
引用列表或符号完全等同于使用特殊形式
(quote…
)。它专门用于使引用的内容不被评估数据或键入REPL中的数据与
(quote data)
相同,计算结果为符号
数据

不带引号的
data
计算为当前范围内变量
data
的值。因此,在REPL:

[1]> (setq data 14)
14
[2]> data
14
第一个表达式的计算结果也是
14
,因为
setq
返回绑定变量的值(在这方面,其作用类似于C中的赋值运算符
=

在上述代码中,您所做的是将名为
temp
的变量设置为包含符号
data
,然后使用
set
(不带
setq
)将名为
data
的变量设置为符号
show
。这有点类似于在Perl中使用软引用(例如),但我不认为它作为Lisp技术得到特别广泛的应用或建议


顺便说一下,您的
display
过程可能也没有按照您的想法执行:它返回一个包含您传递给它的任何内容的元素列表。在REPL中键入值时会打印该值,这是因为任何表达式的值都会在REPL中打印。要在程序中显示值,可以使用
print
,也可以使用。(我假设您使用的是Common Lisp,因为它显然不是Scheme,但可能是其他一些Lisp变体,在这种情况下,该链接不会有帮助。)

您引用的是
数据。如果你想对它进行评估,你应该打电话

(display data)

您正在引用
数据
。如果你想对它进行评估,你应该打电话

(display data)

谢谢你的回答,但是如果你不知道这个变量是否有界呢?我必须编写一个函数,它接受一个键和一个值,如果键不存在,那么我必须执行setq key value,如果键已经存在,那么我将向键添加值。在这种情况下,如果我这样做(storedata键值),如果值没有被绑定,我会得到一个未绑定的错误,我将如何处理这种情况?Common Lisp具有函数
boundp
,您可以在Hyperspec中查找该函数(链接为
格式
的手册)
(boundp'foo)
告诉您
foo
是否作为变量存在于当前范围内,
(boundp var name)
var name
绑定到的任何符号执行相同的操作。不过,使用变量名称空间进行此类操作通常是一种非常糟糕的设计。你应该考虑使用一个变量。但是如果我的函数取了一个未被评估的表达式,我将如何在函数中评估它,这样我就可以得到表达式的值?那么,在函数中的表达式中,我会使用EVE吗?是的,这就是 EVA。不过,我仍然怀疑传递未赋值的Lisp代码块是否是解决问题的最佳方法。也许可以问另一个问题,更详细地说明你想做什么?谢谢你的回答,但是如果你不知道变量是否有界呢?我必须编写一个函数,它接受一个键和一个值,如果键不存在,那么我必须执行setq key value,如果键已经存在,那么我将向键添加值。在这种情况下,如果我这样做(storedata键值),如果值没有被绑定,我会得到一个未绑定的错误,我将如何处理这种情况?Common Lisp具有函数
boundp
,您可以在Hyperspec(手动链接的