TYPEP signals a dubious error combining MEMBER and SATISFIES
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
Won't Fix
|
Undecided
|
Unassigned |
Bug Description
SBCL signals an TYPE-ERROR evaluating the following expression
(typep 0.3 '(and integer (satisfies evenp) (member 1 2 3)))
but not on
(typep 0.3 '(and integer (satisfies evenp)))
There is a discussion on comp.lang.lisp as to whether this behavior is conforming.
The spec says that (and integer (satisfies evenp)) is a valid type specifier, but
it does so in an example. One interpretation might be that the example is
not binding, so (and integer (satisfies evenp)) can be treated as non-conforming,
thus allowing any behavior to (typep 0.3 '(and integer (satisfies evenp))
Nevertheless, SBCL, evaluates that expression to nil.
It is when adding the (member 1 2 3) as the 3rd operand of the and where the
error is encountered.
The SBCL developers might well decide to mark this issue as WONT-FIX. But
I'm filing the bug report in case you believe the SBCL behavior to be
inconsistent.
The relevant pages in the spec are
http://
http://
The latter specifies that (and A B) is the intersection of A and B, implying
that it is the same as (and B A). However, the former gives the example of
(and integer (satisfies evenp)) which violates this supposed principle.
There is a discussion about a conflict between cltl2 and the cl spec
https:/
Apparently section 4.4 of cltl2 forbids an implementation for changing the order
of the operands of the AND type specifier, but the CL specification omits this
restriction.
The comp.lang.lisp discussion:
https:/
Here is the version information.
uname -a
Darwin johan.lrde.epita.fr 15.6.0 Darwin Kernel Version 15.6.0: Sun Jun 4 21:43:07 PDT 2017; root:xnu-
sbcl --version
SBCL 1.3.14
CL-USER> *features*
(:LISP-UNIT :BORDEAUX-THREADS :CLOSER-MOP :THREAD-SUPPORT :SWANK :QUICKLISP
:ASDF-
:NON-BASE-
:ALIEN-CALLBACKS :ANSI-CL :ASH-RIGHT-VOPS :BSD :C-STACK-
:COMMON-LISP :COMPACT-
:COMPLEX-
:FP-AND-
:IMMOBILE-SPACE :INLINE-CONSTANTS :INODE64 :INTEGER-EQL-VOP :LINKAGE-TABLE
:LITTLE-ENDIAN :MACH-EXCEPTION
:MULTIPLY-
:OS-PROVIDES-
:PACKAGE-
:RAW-SIGNED-WORD :SB-DOC :SB-EVAL :SB-LDB :SB-PACKAGE-LOCKS :SB-SIMD-PACK
:SB-SOURCE-
:STACK-
:STACK-
:STACK-
:UNBIND-N-VOP :UNIX :UNWIND-
CL-USER>
I may or may not reply to that group discussion, but I will say that to my reading, the spec nowhere claims that AND specifiers treat terms appearing earlier as guard conditions on terms to their right.
The simplification that we're making is that (MEMBER 1 2 3) *implies* INTEGERP.
Therefore we needn't test both. So it's actually the INTEGER term that drops out, and what remains is (AND (SATISFIES EVENP) (MEMBER 1 2 3))
While it's true that writing terms in a certain order could "fix" this error checking issue, we only make a best effort to preserve order of terms in the first place.
It is generally understood - in my belief anyway - that SATISFIES predicates must be written to accept any object. The example of (AND INTEGER (SATISFIES EVENP)) is foolish.