Common Lisp allows to define types and to declare types for variables, functions, ...
Types are independent from classes - classes are also types, but types can express more (like the range of integers, the size of an array, the element types of an array, ...).
Declaring types may serve a lot of different purposes:
- omit runtime type checks in optimized code
- generation of specialized instructions in optimized code
- compile-time type checks
- optimize allocation of data structures
- runtime type checks
- documentation
Thus the effects of declaring types with certain compiler settings (debug, space, speed, compilation-speed, safety, ..) is not very simple. A Lisp system may ignore much of the declarations or use them widely. The effects can be very different. In some combination of compiler settings declaring a type may make the code a lot slower, in others it may make it a lot faster.
Also, compilers might be able to do some amount of type inference.
A simple declaration might look like this:
(defun add-integer (a b)
(declare (integer a b))
(the integer (+ a b)))
The Lisp system can now do one or more of the following:
- ignore the declaration
- add runtime checks that
a
and b
are
integers and that the result of the + operation is actually an
integer (and not a float, rational or complex number)
- omit runtime checks for the
+
operation
- generate code for a specialized
+
operation, which only works on integers
- do compile-time type checks
Typical compiler settings to achieve above would be:
- safety = 3
- safety = 0
- safety = 0 and speed = 3
But the exact settings and their meaning might differ and should be documented in the specific Lisp implementation manual.
The types are documented in the ANSI Common Lisp Standard. See Types and Classes.
For the compiler settings see for example: SBCL Compiler or LispWorks, The Compiler.
To study the effect of compilation of type declared code one can use disassemble and time.
(declare (type integer var))
wherevar
is a variable bound to the value30
(for example)? – SteamrollerDECLARE
/PROCLAIM
/DECLAIM
to declare types for variables/functions. For struct or class slots you can use the:TYPE
keyword, and for arrays the:ELEMENT-TYPE
. For example,(let ((x 10)) (declare (type integer x)) ...)
. What actually hapens when you declare a type depends on the implementation and optimisation settings. Usually you'll need to favor speed to get optimized code, or safety to get type checking. – Relevant