SBCL Common Lisp中为何非列表cons cell会使LISTP返回T?
问题:为什么
LISTP对非列表的cons cell返回T? 全局变量a是一个cons cell(通过(cons 1 2)创建,值为(1 . 2)),但它并不是一个正规列表,为什么调用(listp a)会返回T?
* (defvar a (cons 1 2)) A * a (1 . 2) * (listp a) T
原因说明
在Common Lisp的标准定义里,LISTP的判定逻辑很直接:只要参数是NULL(空列表())或者CONSP(cons cell),就返回T。它不会区分正规列表(proper list,即最后一个cdr为nil的链式cons结构)和点列表(dotted list,最后一个cdr不为nil的cons结构)。你创建的(1 . 2)属于点列表,本质是一个cons cell,所以LISTP会返回T。
补充:判断正规列表的函数
如果需要判断一个值是否是正规列表,可以使用下面这个函数,感谢Gwang-Jin Kim提供的实现:
(defun proper-list-p (lst) (or (null lst) ; 要么是空列表`()`,要么: (and (consp lst) ; 是一个cons cell (listp (cdr lst)) ; cdr部分是cons cell或空列表 (null (cdr (last lst))) ; 不是点列表 (not (tailp lst (cdr lst)))))) ; 不是循环列表
内容的提问来源于stack exchange,提问作者Scooter
相关产品推荐
相关产品推荐

