Maybe this question is too general, nevertheless i\'ll try: Is there any comprehensive guide on types in common lisp?
I\'m kind of confused about this subject:
You need to tell the compiler to optimize for safety if you want it to actually enforce the types:
CL-USER> (declaim (optimize (safety 3)))
NIL
CL-USER> (defclass foobar () ())
#
CL-USER> (defun foo (a)
(make-array 1 :element-type 'foobar
:initial-contents (list a)))
FOO
CL-USER> (foo (make-instance 'foobar))
#(#)
CL-USER> (foo 12)
;=> ERROR
CL-USER> (declaim (ftype (function (integer integer) integer) quux))
(QUUX)
CL-USER> (defun quux (a b)
(+ a b))
QUUX
CL-USER> (quux 12 12)
24 (5 bits, #x18, #o30, #b11000)
CL-USER> (quux 12 "asd")
;=> ERROR
Checking the types at run-time adds some overhead (especially if it happens in a loop), and may be done multiple times for a single value, so it's not done by default.
(declaim (optimize (safety 3)))
(defun some-predicate-p (a)
(format t "~&Checking type...")
(integerp a))
(deftype foo () `(satisfies some-predicate-p))
(defclass bar ()
((foo :type foo :initarg :foo)))
(declaim (ftype (function (foo) list) qwerty))
(defun qwerty (foo)
(loop repeat 10 collecting (make-instance 'bar :foo foo)))
(qwerty 12)
; Checking type...
; Checking type...
; Checking type...
; Checking type...
; Checking type...
; Checking type...
; Checking type...
; Checking type...
; Checking type...
; Checking type...
; Checking type...
;=> (# # #
; # # #
; # # #
; #)
If you want a function to always check the type of a place, regardless of the optimization settings, you should use CHECK-TYPE manually.