We consider TYPEP to be foldable for change-classable instances:
(defclass foo () ())
(defclass bar () ())
(let* ((f (compile nil `(lambda () (let ((x #.(make-instance 'foo))) (when (typep x 'foo) x)))))
(a (funcall f))
(at (type-of a)))
(change-class a 'bar)
(let* ((b (funcall f))
(bt (type-of b)))
(list (list at a)
(list bt b))))
"Ie. don't do that."
KEYWORDP situation seems somewhat similar, but is admittedly complicated by the standard irritatingly claiming that there are no destructive operations on symbols... argh.
For me the biggest issue here are the consistency issues between various type-introspection functions. (As exemplified by your TYPE-OF case.) Fixing TYPE-OF seems simple enough, but I'm not offhand sure if there are other holes where this can appear.
Douglas: is this just an irritating quirk, or are you getting bad code due to this?
One option would be to have something like
function SB-EXT:MAKE-KEYWORDS-PERMANENT
Makes it impossible to unintern a keyword, allowing KEYWORDP to be constant-folded.
(or *ALLOW-UNINTERNING-KEYWORD* or whatever -- details are details.)
We consider TYPEP to be foldable for change-classable instances:
(defclass foo () ())
(defclass bar () ())
(let* ((f (compile nil
`(lambda ()
(let ((x #.(make-instance 'foo)))
(when (typep x 'foo)
x)))))
(a (funcall f))
(at (type-of a)))
(change-class a 'bar)
(let* ((b (funcall f))
(bt (type-of b)))
(list (list at a)
(list bt b))))
"Ie. don't do that."
KEYWORDP situation seems somewhat similar, but is admittedly complicated by the standard irritatingly claiming that there are no destructive operations on symbols... argh.
For me the biggest issue here are the consistency issues between various type-introspection functions. (As exemplified by your TYPE-OF case.) Fixing TYPE-OF seems simple enough, but I'm not offhand sure if there are other holes where this can appear.
Douglas: is this just an irritating quirk, or are you getting bad code due to this?
One option would be to have something like
function SB-EXT: MAKE-KEYWORDS- PERMANENT
Makes it impossible to unintern a keyword, allowing KEYWORDP to be constant-folded.
(or *ALLOW- UNINTERNING- KEYWORD* or whatever -- details are details.)