lisp - 理解 Common Lisp 中的函数 `tailp`
问题描述
在浏览 Bert Burgemeister 的“Common Lisp Quick Reference”时,我绊倒了tailp
。
首先,我误解了这个函数的定义。我试过了:
(tailp '(3 4 5) '(1 2 3 4 5))
但它回来了
NIL
CLTL2说,如果第一个参数是任何现有的,tailp
则为真。(nthcdr n list)
n
(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
: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
的给定列表eq
的任何导数?”。
但也许有人可以向我解释这种测试在哪些情况下非常有用?
评论:
在与@Lassi的长时间讨论中,我们发现:
切勿tailp
在循环列表中使用!
因为行为是未定义的(已经在 SBCL 中有问题)。tailp
用于非循环列表也是如此。
解决方案
的基本目的tailp
是检查是否有共享的列表结构。这意味着cons 单元格是否相同(这意味着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
这是 Common Lisp 中很少使用的函数之一。
推荐阅读
- python - 问题在 PyCharm 中运行 Python 3.7 以执行 Twitter Bot(通过 Tweepy)
- javascript - 具有不透明边缘的实心圆环 - THREE.js
- java - 我正在尝试将扫描仪输入用于 for 循环,该循环计算从最小值到最大值的数字并在终端中显示数字
- java - MySQL Connector/J 驱动程序是否实现 JdbcRowSet 接口?
- omnet++ - 如何使用 setDoubleValue() 在 Omnet++ 中更改参数运行时
- dart - 如何修复向特定Web服务器发出http请求的flutter web http错误
- r - 我可以在不终止 R 会话的情况下停止正在进行的操作吗?
- python - 如何在循环数据框时将数据添加到绘图
- mysql - 按年龄查找数据库中每个人的计数
- firebase - Flutter FirebaseDatabase 运行事务崩溃