Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Common Lisp type declarations not working as expected

When I define a function in Common Lisp like this:

(defun foo (n)
  (declare (type fixnum n))
  (+ n 42))

I expected a call like (foo "a") to fail right away but it instead fail at the call to +. Is the declare form not guarantees static type checking?

like image 730
Eli Schneider Avatar asked Mar 01 '12 18:03

Eli Schneider


1 Answers

Type declarations are traditionally meant to be used as guarantees to the compiler for optimization purposes. For type checking, use check-type (but note that it, too, does the checking at run-time, not at compile-time):

(defun foo (n)
  (check-type n fixnum)
  (+ n 42))

That said, different Common Lisp implementations interpret type declarations differently. SBCL, for example, will treat them as types to be checked if the safety policy setting is high enough.

In addition, if you want static checking, SBCL is probably your best bet as well, since its type inference engine warns you about any inconsistencies it encounters. To that end, ftype declarations can be put to good use:

CL-USER(1): (declaim (ftype (function (string) string) bar))

CL-USER(2): (defun foo (n)
              (declare (type fixnum n))
              (bar n))
; in: DEFUN FOO
;     (BAR N)
; 
; caught WARNING:
;   Derived type of N is
;     (VALUES FIXNUM &OPTIONAL),
;   conflicting with its asserted type
;     STRING.
;   See also:
;     The SBCL Manual, Node "Handling of Types"
; 
; compilation unit finished
;   caught 1 WARNING condition

FOO
like image 174
Matthias Benkard Avatar answered Oct 06 '22 20:10

Matthias Benkard