admin管理员组文章数量:1122833
Global variable a is a cons cell, but NOT a list. Why does LISTP return T for it?
* (defvar a (cons 1 2))
A
* a
(1 . 2)
* (listp a)
T
Edit: Thanks to Gwang-Jin Kim for a function to substitute for what I wanted:
(defun proper-list-p (lst)
(or (null lst) ; either a `'()` or:
(and (and (consp lst) ; a cons
(listp (cdr lst))) ; a cons that has a cons cell or null as CDR
(null (cdr (last lst))) ; not a dotted list
(not (tailp lst (cdr lst)))))) ; not circular
Global variable a is a cons cell, but NOT a list. Why does LISTP return T for it?
* (defvar a (cons 1 2))
A
* a
(1 . 2)
* (listp a)
T
Edit: Thanks to Gwang-Jin Kim for a function to substitute for what I wanted:
(defun proper-list-p (lst)
(or (null lst) ; either a `'()` or:
(and (and (consp lst) ; a cons
(listp (cdr lst))) ; a cons that has a cons cell or null as CDR
(null (cdr (last lst))) ; not a dotted list
(not (tailp lst (cdr lst)))))) ; not circular
Share
Improve this question
edited Nov 30, 2024 at 15:56
Scooter
asked Nov 21, 2024 at 17:22
ScooterScooter
7,0618 gold badges44 silver badges72 bronze badges
1
|
2 Answers
Reset to default 3From CLHS
Returns true if object is of type
list
; otherwise, returns false.
and the definition of the type list
is:
The types
cons
andnull
form an exhaustive partition of the typelist
.
Since (1 . 2)
is a cons
, it's also a list
.
(listp object) == (typep object 'list) == (typep object '(or cons null))
For efficiency, listp
doesn't try to determine if it's a proper list, which ends with NIL
. There's no standard function that does this. See Check for proper list in Common Lisp
The listp
doesn't check whether it is a proper list or not (with last element of the conses being NIL).
(Incorrect!!) To check for a proper list:
(defun proper-list-p (lst)
(or (null lst) ; either a `'()` or:
(and (consp lst) ; a cons
(not (tailp lst (cdr lst))) ; not circular
(null (cdr (last lst)))))) ; not a dotted list
As @Scooter pointed out, the tailp
test needs to be pretested
for the case that (cdr lst)
is not a list/cons.
Then (proper-list-p (cons 1 2))
doesn't throw an error which
tailp
throws when testing a tail which is a non-nil atom!
So this is the final, correct version:
(defun proper-list-p (lst)
(or (null lst) ; either a `'()` or:
(and (consp lst) ; a cons
(and ; not circular:
(listp (cdr lst)) ; - evade tailp error
(not (tailp lst (cdr lst)))) ; - test non-circularity
(null (cdr (last lst)))))) ; not a dotted list
Now, we get:
(proper-list-p '()) ;; => T
(proper-list-p (cons 1 2)) ;; => NIL
(proper-list-p 1) ;; => NIL (any non-nil atom)
(proper-list-p (list 1 2 3)) ;; => T
本文标签: predicateWhy does listp in SBCL Common Lisp return T for a nonlist cons cellStack Overflow
版权声明:本文标题:predicate - Why does listp in SBCL Common Lisp return T for a non-list cons cell? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736308542a1933698.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
(cons 1 2)
is a list; it's just not a proper list - which is not whatlistp
is checking for. All it does is distinguish between a cons cell and an atom. – jasonharper Commented Nov 21, 2024 at 17:34