清单项目评估

jmq*_*jmq 1 lisp emacs 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"
Run Code Online (Sandbox Code Playgroud)

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

这是emacs 24中的elisp.

spi*_*ike 8

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

(setq stuff (quote (one two three (+ 2 2))))
Run Code Online (Sandbox Code Playgroud)

引用的论点是表达式(one two three (+ 2 2)).

来自http://www.gnu.org/software/emacs/manual/html_node/elisp/Quoting.html:"特殊表格引用返回其单个参数,如编写而不评估它".


Chr*_*ett 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.
Run Code Online (Sandbox Code Playgroud)

语法转换:

(setq x '(string-to-int "123"))
(setf (car x) 'string-to-list)
x                                   ; => '(string-to-list "123")
Run Code Online (Sandbox Code Playgroud)

延迟评估:

(setq x '(message "Hello World"))   ; => '(message "Hello World")
(eval x)                            ; => "Hello World"
Run Code Online (Sandbox Code Playgroud)

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

`(1 2 (+ 3 4))     ; => '(1 2 (+ 3 4))   
`(1 2 ,(+ 3 4))    ; => '(1 2 7)         ;; Note the comma!
Run Code Online (Sandbox Code Playgroud)

语法quote还允许使用以下语法进行列表拼接,@:

`(1 2 ,@(+ 3 4))   ; => '(1 2 + 3 4)
Run Code Online (Sandbox Code Playgroud)

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


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

 (list 1 2 (+ 3 4)) ; => '(1 2 7)
Run Code Online (Sandbox Code Playgroud)