清单项目评估

时间:2012-12-31 22:03:15

标签: emacs lisp elisp

我正在学习lisp并对一个简单的列表有疑问:

(setq stuff '(one two three (+ 2 2)))
stuff ; prints "one two three (+ 2 2)"

(setq stuff (list `one `two `three (+ 2 2)))
stuff ; prints "one two three 4"

第一个setq创建一个列表“one two three(+ 2 2)”。第二个列表创建“一二三四”。为什么第一个列表不评估(+ 2 2),但第二个列表没有?我在Emacs Lisp介绍文档中读到,当列表构建时,它从内到外进行评估。为什么第一个列表在将其添加到列表之前不评估添加?

这是emacs 24中的elisp。

2 个答案:

答案 0 :(得分:8)

'不等同于list,它是quote的简写。你真的是这样做的:

(setq stuff (quote (one two three (+ 2 2))))

引用的参数是表达式(one two three (+ 2 2))

来自http://www.gnu.org/software/emacs/manual/html_node/elisp/Quoting.html:“特殊形式引用返回其单个参数,如编写,未经评估”。

答案 1 :(得分:8)

看起来你正在研究Lisp的评估语义,所以继续玩吧!

您可以将quote视为抑制其参数的评估。这允许您编写可以操作或传递的表达式。它还用于编写不应被评估为函数调用的数据结构。

数据结构:

'(1 2 3)    ; => '(1 2 3)
(1 2 3)     ; => Lisp error: (invalid-function 1) 

;; The Lisp reader sees the number 1 in the function position and tries to call it, signalling an error.

语法转换:

(setq x '(string-to-int "123"))
(setf (car x) 'string-to-list)
x                                   ; => '(string-to-list "123")

延迟评估:

(setq x '(message "Hello World"))   ; => '(message "Hello World")
(eval x)                            ; => "Hello World"

有一个密切相关的特殊运算符,名为语法引用,使用反引号编写。它允许您使用逗号(,)运算符评估带引号的表达式中的各个表单。它就像quote一样有一个逃生舱。

`(1 2 (+ 3 4))     ; => '(1 2 (+ 3 4))   
`(1 2 ,(+ 3 4))    ; => '(1 2 7)         ;; Note the comma!

语法quote还允许使用,@语法列表拼接

`(1 2 ,@(+ 3 4))   ; => '(1 2 + 3 4)

如您所见,它将后续表达式拼接到包含表达式中。在你开始编写宏之前,你可能不会经常看到它。


另一方面,

list是一个简单的功能。它评估其参数,然后返回包含这些项的新数据结构。

 (list 1 2 (+ 3 4)) ; => '(1 2 7)