gpt4 book ai didi

common-lisp - On Lisp 的 #[ read 宏中引用的必要性?

转载 作者:行者123 更新时间:2023-12-02 01:50:04 24 4
gpt4 key购买 nike

我正在阅读 On Lisp 并且无法弄清楚为什么下面的代码使用了引号。这是文本的摘录:

Another character combination reserved for the user is #[. Figure 17.3 gives an example of how this character might be defined as a more elaborate kind of left parenthesis. It defines an expression of the form #[x y] to read as a list of all the integers between x and y, inclusive:

#[2 7]
(2 3 4 5 6 7)

Figure 17.3: A read-macro defining delimiters.

(set-macro-character #\] (get-macro-character #\)))

(set-dispatch-macro-character #\# #\[
#'(lambda (stream char1 char2)
(let ((accum nil)
(pair (read-delimited-list #\] stream t)))
(do ((i (ceiling (car pair)) (1+ i)))
((> i (floor (cadr pair)))
(list 'quote (nreverse accum)))
(push i accum)))))

Figure 17.3: A read-macro defining delimiters.

我不明白为什么 do** 结果表中的行是 **(list 'quote (nreverse accum))) 而不是 (nreverse accum) .因为我们可以毫无问题地运行下面不使用引号的代码,对吧?

(let ((acc nil))
(do ((i 2 (1+ i)))
((> i 7)
(nreverse acc))
(push i acc)))

有人知道这里的技巧吗?

最佳答案

如果您在 Lisp 监听器中输入新语法,读取器将返回一个数字列表。评估这个数字列表将是一个错误,因为 Lisp 期望函数或宏作为列表的头部。列表不会像向量、数字、哈希表...那样对自身求值。

因此你有两个选择:

  1. 让用户在区间表达式前写一个引号以防止计算
  2. 返回一个引用列表

这里我们看到选项 2。

CL-USER 7 > (read-from-string "#[5 10]")
(QUOTE (5 6 7 8 9 10))

CL-USER 8 > (eval (read-from-string "#[5 10]"))
(5 6 7 8 9 10)

CL-USER 9 > (let ((e #[5 10]))
(describe e))

(5 6 7 8 9 10) is a LIST
0 5
1 6
2 7
3 8
4 9
5 10

如果阅读器宏不返返回价列表表单,我们将不得不编写:

CL-USER 10 > (let ((e '#[5 10]))   ; notice the QUOTE
(describe e))

(5 6 7 8 9 10) is a LIST
0 5
1 6
2 7
3 8
4 9
5 10

嗯,我个人其实更喜欢后者,必须明确地写下引文。

我得到:

CL-USER 17 > '(#[5 10] #[20 25])
((QUOTE (5 6 7 8 9 10)) (QUOTE (20 21 22 23 24 25)))

但我更愿意:

CL-USER 18 > '(#[5 10] #[20 25])
((5 6 7 8 9 10) (20 21 22 23 24 25))

关于common-lisp - On Lisp 的 #[ read 宏中引用的必要性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23321120/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com