KEYWORDP should be Foldable
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
New
|
Undecided
|
Unassigned |
Bug Description
Compile-time type inference re. keywords is wrong or overly conservative due to KEYWORDP being flushable but not foldable.
A few examples:
* (sb-c::ctypep :kw42 (sb-c::
* (sb-c::
* (sb-c::csubtypep (sb-c::
This problem is version- and system-independent - It's been this way forever.
With this simple patch, all existing tests pass, and the above return T
-(defknown keywordp (t) boolean (flushable)) ; If someone uninterns it...
+(defknown keywordp (t) boolean (foldable flushable))
The elliptical comment about unintern probably expressed concern due to side-effects on the symbol-package, as in:
* (let ((s (make-symbol "HI123"))) (print (keywordp s)) (import s 'keyword) (print (keywordp s)) (unintern s 'keyword) (print (keywordp s)) (values))
which prints NIL then T then NIL.
But per the explanation of FOLDABLE in "knownfun.lisp" this is ok because
"The function has no side effects, but _MAY_ be affected by side effects on the arguments." [my emphasis]
And fwiw, Clozure which borrows from the CMUCL framework enough that the exact same tests can be run, but with a completely different underlying implementation, agrees on this:
? (ccl::csubtypep (ccl::specifier
T
T
Yes, that is one way to fix this. Unfortunately:
CL-USER> (defvar *keyword* :foo)
*KEYWORD*
CL-USER> (keywordp *keyword*)
T
CL-USER> (unintern *keyword* :keyword)
T
CL-USER> (keywordp *keyword*)
NIL
I'm inclined to ignore the issue, but that'd be another case of note quite implementing Common Lisp.