在Lisp(Clojure,Emacs Lisp)中,列表和引用之间有什么区别?

neo*_*neo 29 lisp elisp list clojure quote

从阅读关于Lisp的介绍材料,我现在认为以下内容是相同的:

(list 1 2 3)

'(1 2 3)
Run Code Online (Sandbox Code Playgroud)

但是,从我在Clojure和Emacs Lisp中使用引用形式时遇到的问题来看,它们并不相同.你能告诉我有什么区别吗?

Ale*_*art 35

主要区别在于quote阻止了对元素的评估,而list 不是:

user=> '(1 2 (+ 1 2))
(1 2 (+ 1 2))
user=> (list 1 2 (+ 1 2))
(1 2 3)

出于这个原因(以及其他),在描述文字集合时使用向量是惯用的clojure:

user=> [1 2 (+ 1 2)]
[1 2 3]


Tre*_*son 9

'(1 2 3)应谨慎处理引用列表(例如)(通常为只读).(参见SO答案何时使用Lisp中的'引用何时使用'在Lisp中引用).

(list 1 2 3) 将"收集"一份新的清单,独立于所有其他清单.

您可以在手册中nconc看到使用引用列表的陷阱示例.

并且,正如您可能知道的那样,当您调用时'list- 显然将根据引用列表的内容来评估参数.并且'quote采用单个参数,而不是'list可变数量的参数.

(list (+ 1 2) 3)     -->  (3 3)
(quote ((+ 1 2) 3))  -->  ((+ 1 2) 3)
Run Code Online (Sandbox Code Playgroud)


Rai*_*wig 8

在Common Lisp中,引用的对象是常量文字数据.您不应修改此数据,因为后果未定义.可能的后果是:修改共享数据,尝试修改只读数据,可能会发出错误信号,它可能正常工作,......

对于列表:

'(1 2 3)
Run Code Online (Sandbox Code Playgroud)

上面是一个常量列表,它将由读者构建并对其自身进行评估,因为它是引用的.如果它出现在Lisp代码中,编译器将以某种方式将此数据嵌入到FASL代码中.

(quote (1 2 3)) 写它是另一种方式.

(list 1 2 3)
Run Code Online (Sandbox Code Playgroud)

这是一个LIST带有三个参数的Common Lisp函数的调用1,23.评估时,结果是一个全新的列表(1 2 3).

类似:

'(1 . 2)   and  (cons 1 2)

'#(1 2 3)  and  (vector 1 2 3)
Run Code Online (Sandbox Code Playgroud)

一个是文字数据,另一个是构造这种数据结构的函数调用.