在浏览伯特·伯格迈斯特( Bert Burgemeister )的“通用Lisp快速参考”()时,我偶然发现了tailp。
首先,我误解了这个函数的定义。我试过:
(tailp '(3 4 5) '(1 2 3 4 5))但它又回来了
NILCLTL2说,tailp是真实的,当且仅当,第一个论点是任何有现有n的(nthcdr n list)。
(nthcdr 2 '(1 2 3 4 5))
;; (3 4 5)我进一步努力:
(tailp '(3 4 5) '(1 2 3 4 5))
;; NIL - and I would expect: T following the definition above.
(tailp '() '(1 2 3 4 5))
;; T
(tailp '5 '(1 2 3 4 . 5))
;; T直到我尝试(然后理解了tailp查找共享相同地址的cdr of l ):
(defparameter l '(1 2 3 4 5 6))
(tailp (nthcdr 3 l) l)
;; T但后来我有了下一个问题:
For what such a function is useful at all?看看子列表是否是列表的一部分,难道不是一个更有用的函数吗?(或者看起来像列表的一部分,而不是必须共享相同的地址?)
备注:
啊,好吧,慢慢地,我开始明白了,也许这是一种对列表中的eq部分的cdr .有点..。“对于第一个参数,给定的列表( cdr-derivative of eq )有吗?”
但也许有人能解释一下,在什么情况下这样的测试是非常有用的?
备注:
在与@Lassi here的长时间讨论中,我们发现:
从不在循环列表中使用!
因为行为是未定义的(在SBCL中已经有问题)。因此,tailp适用于非循环列表。
发布于 2018-05-26 20:14:59
tailp的基本目的是检查是否存在共享的列表结构。这意味着反单元格是否是相同的(这意味着EQL作为谓词),而不仅仅是cons单元格的内容。
还可以检查项目是否在最后一个cdr中。
CL-USER 87 > (tailp t '(1 2 3 4 . t))
T
CL-USER 88 > (tailp nil '(1 2 3 4 . nil))
T
CL-USER 89 > (tailp nil '(1 2 3 4))
T
CL-USER 90 > (tailp #1="e" '(1 2 3 4 . #1#))
T这是公共Lisp中很少使用的函数之一。
发布于 2018-05-29 21:50:54
下面是tailp有用的一个例子:
(defun circular-list-p (l)
(and (consp l)
(tailp l (rest l))))几个音符。
这在所有情况下都会终止:如果第一个参数不是第二个参数的尾(即不要求它检查循环性),则不允许tailp在循环列表中终止,但如果第一个参数是第二个参数的尾,则它必须终止。但是,如果列表是循环的,这正是我们在这里检查的,所以它终止了。(我对此感到困惑了一段时间)。
consp检查是错误的,所以(circular-list-p nil)是错误的:我认为这是一个实用的选择,尽管您可能会认为nil是循环的。
发布于 2018-05-28 18:57:33
我非常肯定(tailp '(3 4 5) '(1 2 3 4 5))的答案可以是t和nil,因为智能编译器可能会做(tailp '#1=#(3 4 5) '(1 2 . #1#))来减少内存占用。引用的东西是不变的文字,那么为什么不使用相同的内存两次呢?
下面是tailp的工作方式:
(defparameter *tail* (list 3 4 5))
(defparameter *larger* (list* 1 2 *tail*))
(defparameter *replica* (copy-list *larger*))
(tailp *tail* *replica*) ; ==> nil
(tailp *tail* *larger*) ; ==> t由于copy-list为列表中的每个元素创建了新的缺点,它将只与任何其他列表共享空列表。它是独一无二的。
*larger*是与*tail*共同制作的,因此(tailp *tail* *larger*)将是t。
重要的是将参数作为相同的对象进行比较。因为尾巴不需要是一个列表,所以它与eql相比。在比较时,如果使用的是相同的内容,则使用equal,因此tailp比这更具体。它必须是指针相等(eq)或eql原子值。
你在哪用这个?我正在考虑一种功能数据结构,在这种结构中,您通常重用共享结构。tailp可用于标识父级的子树。它基本上是一个更有表现力的版本:
(defun my-tailp (needle haystack)
(cond ((eql needle haystack) t)
((atom haystack) nil)
(t (my-tailp needle (cdr haystack)))))https://stackoverflow.com/questions/50542453
复制相似问题