Typing variables in Common Lisp

Viewed 4298

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?

2 Answers

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).
Related