Reputation: 375
I read that CL supports optional typing (as in the language has this feature) which I would assume allos for faster code in many cases, but I can't seem to find anything about actually writing typed code. Is it possible to explicitly type code instead of using hacks? (for example, #'vector
generates a simple-vector
, kinda reminds me of |0
in JS to coerce to an integer)
Or maybe since types are actually CLOS classes (they are, right?) you simply have to #'make-instance
an object of type, say, 'integer
?
Upvotes: 6
Views: 6967
Reputation: 139251
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:
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:
a
and b
are
integers and that the result of the + operation is actually an
integer (and not a float, rational or complex number)+
operation+
operation, which only works on integersTypical compiler settings to achieve above would be:
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.
Upvotes: 6
Reputation: 18375
For performance tuning see https://lispcookbook.github.io/cl-cookbook/performance.html
For compile-time type warnings see https://lispcookbook.github.io/cl-cookbook/type.html
You can give type hints like this:
(defun max-with-type (a b)
(declare (optimize (speed 3) (safety 0)))
(declare (type integer a b))
(max a b))
and use the
:
(defun do-some-arithmetic (x)
(declare (optimize (speed 3) (debug 0) (safety 0)))
(the fixnum (+ x (square x))))
Using declaim will also give more type warnings at compile time.
It is possible to type variables:
(declaim (type (string) *name*))
(defparameter *name* "book")
We can compose types ((or null string)
) and use our owns (declared with deftype
).
You can declare function types with declaim
, or with declare
inside the function:
(declaim (ftype (function (fixnum) fixnum) add))
;; ^^input ^^output [optional]
(defun add (n)
(+ n 1))
With this we get nice type warnings at compile time.
If we change the function to erroneously return a string instead of a fixnum, we get a warning:
(defun add (n)
(format nil "~a" (+ n 1)))
; caught WARNING:
; Derived type of ((GET-OUTPUT-STREAM-STRING STREAM)) is
; (VALUES SIMPLE-STRING &OPTIONAL),
; conflicting with the declared function return type
; (VALUES FIXNUM &REST T).
Upvotes: 4