Previous: , Up: Types in Python   [Contents][Index]


4.5.3 Weakened Type Checking

When the value for the speed optimization quality is greater than safety, and safety is not 0, then type checking is weakened to reduce the speed and space penalty. In structure-intensive code this can double the speed, yet still catch most type errors. Weakened type checks provide a level of safety similar to that of “safe” code in other Common Lisp compilers.

A type check is weakened by changing the check to be for some convenient supertype of the asserted type. For example, (integer 3 17) is changed to fixnum, (simple-vector 17) to simple-vector, and structure types are changed to structure. A complex check like:

(or node hunk (member :foo :bar :baz))

will be omitted entirely (i.e., the check is weakened to *.) If a precise check can be done for no extra cost, then no weakening is done.

Although weakened type checking is similar to type checking done by other compilers, it is sometimes safer and sometimes less safe. Weakened checks are done in the same places is precise checks, so all the preceding discussion about where checking is done still applies. Weakened checking is sometimes somewhat unsafe because although the check is weakened, the precise type is still input into type inference. In some contexts this will result in type inferences not justified by the weakened check, and hence deletion of some type checks that would be done by conventional compilers.

For example, if this code was compiled with weakened checks:

(defstruct foo
  (a nil :type simple-string))

(defstruct bar
  (a nil :type single-float))

(defun myfun (x)
  (declare (type bar x))
  (* (bar-a x) 3.0))

and myfun was passed a foo, then no type error would be signaled, and we would try to multiply a simple-vector as though it were a float (with unpredictable results.) This is because the check for bar was weakened to structure, yet when compiling the call to bar-a, the compiler thinks it knows it has a bar.

Note that normally even weakened type checks report the precise type in error messages. For example, if myfun’s bar check is weakened to structure, and the argument is nil, then the error will be:

Type-error in MYFUN:
  NIL is not of type BAR

However, there is some speed and space cost for signaling a precise error, so the weakened type is reported if the speed optimization quality is 3 or debug quality is less than 1:

Type-error in MYFUN:
  NIL is not of type STRUCTURE

See optimize-declaration for further discussion of the optimize declaration.


Previous: Precise Type Checking, Up: Types in Python   [Contents][Index]