我在阅读 Bert Burgemeister 的“Common Lisp Quick Reference”时,发现了tailp
。
起初,我对这个函数的定义产生了误解。然后我尝试了:
(tailp '(3 4 5) '(1 2 3 4 5))
但是它返回了。
NIL
CLTL2中说,
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
寻找共享同一地址的 l
的 cdr
,我才明白:
(defparameter l '(1 2 3 4 5 6))
(tailp (nthcdr 3 l) l)
;; T
但随即我有了另一个问题:
For what such a function is useful at all?
一个更有用的函数是查找子列表是否是列表的一部分?(或者看起来像列表的一部分,而不是必须共享相同的地址?)
备注:
啊,好的,慢慢地我开始理解了,也许这就是对于列表的cdr部分的一种eq...有点像..."给定列表的任何cdr导数等于第一个参数?"
但也许有人可以解释一下在哪些情况下这种测试非常有用?
备注:
在与@Lassi的长时间讨论中here,我们发现:
永远不要在循环列表上使用tailp!
因为行为未定义(在SBCL中已经有问题)。所以tailp适用于非循环列表。
TAILP
检查OP2-TAIL
是否是OP1-TAIL
的cdr的尾部,这意味着OP1
在优先级列表中排名第一。 - jkiiskiTAILP
可以作为列表内优先级/后继测试...由于它直接查看位置,因此可能比其他构造的测试更有效,不是吗? - Gwang-Jin Kim