Lisp Sharpsign等号读取器宏的示例?

Lisp Sharpsign等号读取器宏的示例?,lisp,common-lisp,Lisp,Common Lisp,我曾经见过这个,但不明白它的作用。参考书上说是的 #n=object读取对象的打印表示形式。 但是,该对象用n标记,a是必需的 无符号十进制整数,用于语法#n#的可能引用。 标签的作用域是最外层读取的表达式 呼吁阅读;在此表达式中,可能不会出现相同的标签 两次 在我看来,这只是随机选择的56个英语单词。。。您能举例说明何时可以使用它吗?在Common Lisp中,读卡器和打印机使用它。 通过这种方式,可以在某些s表达式中标记对象,并在s表达式中的其他位置引用该对象 标签是#someinteger

我曾经见过这个,但不明白它的作用。参考书上说是的

#n=object
读取对象的打印表示形式。 但是,该对象用n标记,a是必需的 无符号十进制整数,用于语法#n#的可能引用。 标签的作用域是最外层读取的表达式 呼吁阅读;在此表达式中,可能不会出现相同的标签 两次


在我看来,这只是随机选择的56个英语单词。。。您能举例说明何时可以使用它吗?

在Common Lisp中,读卡器和打印机使用它。

通过这种方式,可以在某些s表达式中标记对象,并在s表达式中的其他位置引用该对象

标签是
#someinteger=
,后跟一个s表达式。整数必须是唯一的。在一个s表达式中不能两次使用标签

对标签的引用是
#someinteger#
。整数标识要引用的s表达式。必须先引入标签,然后才能引用它。该引用可以在s表达式中多次使用

例如,这用于读取和打印具有共享数据对象的循环列表或数据结构

这里有一个简单的例子:

? '(#1=(1 . 2) (#1#))
读作

((1 . 2) ((1 . 2)))
还要注意这一点:

? (eq (first *) (first (second *)))
T
这是一个完全相同的细胞

让我们试试循环列表

确保打印机处理循环列表,并且不会永远打印它们

? (setf *print-circle* t)
T
现在我们正在构建一个列表:

? (setf l1 (list 1 2 3))
(1 2 3)
我们正在将最后一个cdr设置为第一个cons:

? (setf (cdr (last l1)) l1)
#1=(1 2 3 . #1#)
如上所示,打印的列表得到一个标签,最后一个cdr是对该标签的引用

我们也可以使用相同的符号直接输入循环列表。读者理解它:

? '#1=(1 2 3 . #1#)
#1=(1 2 3 . #1#)
由于我们已告知打印机处理此类构造,我们可以尝试第一个示例中的表达式:

? '(#1=(1 . 2) (#1#))
(#1=(1 . 2) (#1#))

现在打印机检测到对同一cons对象有两个引用。

read
是一个递归操作。对于列表,
是一个宏字符,递归读取,直到
。最后一句话的意思是,您不能在
读取中使用相同的标签,即
(#1=1#1=2#1#))
无效,标签
1
在同一最外层读取调用中使用两次。加载或编译文件时,每个顶级表单都将在一个单独的最外层的
read
调用中读取,因此在不同的顶级表单中使用相同的标签是没有问题的,因为它们根本不相关。Let Over Lambda中还有一节介绍循环表达式:我想你现在已经了解了,但是你引用的文字足以理解标签是什么。在
#n=
中,
n
是标签,是一个无符号整数。哈希后面的数字(CLHS中的锐符号)通常是分派宏字符的参数。因此,它是一个介于
=
之间的数字,用于标记,
用于引用。在加载或编译的文件中,每个顶级表达式都是单独读取的,因此每个表达式都是最外层的读取。在REPL中,通常每个提示符开始最外层的读取。
#1=(可编程。#1#)
on#lisp