Currently one of the ways to blindside SBCL's
declarationsareassertions policy is to specify a subtype of FUNCTION
as a defstruct slot type:
(defstruct foo
(bar (error "missing arg") :type (function (cons) cons)))
(defun quux (bar x)
(declare (optimize safety))
(let ((y (funcall (foobar bar) x)))
(setf (car y) 1
(car x) 1)
(values x y)))
(quux (makefoo :bar (lambda (x) (reverse x)))
"not a cons!")
; => "n", "!"
...oops. Either the slot setters need to check the derived type, or
the type has to be properly upgraded to FUNCTION.
I think the latter is TRT, since in the above example it is the caller
that is wrong  the function itself is fine as long as it is called
with a proper list nonempty list.
This is not defstruct specific, but applies to subtypes of FUNCTION in
pretty much all contexts:
(declaim (ftype (function () (function (cons) cons)) fii))
(defun fii ()
(lambda (x) x))
(defun feh (x)
(let ((y (funcall (fii) x)))
(setf (car y) 3)
y))
(feh "foobar") ; => "foo"
Even if checking the derived type for defstruct slots would be
acceptable, I don't think doing it for all function in general is. To
me this seems to imply the need for a UPGRADEDASSERTIONTYPE or
similar.
Assuming this is done, however, I think we should still make it
possible to enjoy the benefits of derived function types  without
letting go of the safety net entirely:
(declaim (inline %computeconsfunction))
(defun computeconsfunction (x)
(let ((fun (%computeconsfunction)))
(checkfunctiontype fun '(function (cons) cons))
(trulythe (function (cons) cons) fun)))
;;; Add methods to taste...
(defgeneric %computeconsfunction (x))
Analogous examples for DEFSTRUCT exist as well, of course. However,
CHECKFUNCTIONTYPE cannot be written portably. I would like to add
SBEXT:FTYPEP, which make it possible:
(defun ftypep (function ftype)
"Returns true if FUNCTION is a function whose derived type is a subtype of
FTYPE."
(values
(and (functionp function)
(let ((targetctype (sbkernel:specifiertype ftype))
(realctype (sbkernel:specifiertype
(sbimpl::%funtype function))))
(sbkernel:csubtypep realctype targetctype)))))
(ftypep (lambda (x) (reverse x))
'barfunction) ; => NIL
(ftypep (lambda (x) (declare (cons x)) (the cons (reverse x)))
'barfunction) ; => T
For what it's worth, I've had good experiences personally so far using
CHECKFUNCTIONTYPE in things like the %COMPUTECONSFUNCTION above 
which I added after realizing the problem with trusting the function
type while looking for the cause of mysterious memory corruption...
Objections or other comments?
Cheers,
 Nikodemus
