Page 1 of 1

Using static typing in CL

Posted: Tue Nov 25, 2008 6:53 am
by TPJ
Hello.

I'm new to Lisp. I've heard that it's possible to declare the type of variables in Lisp. I find declaring types very useful, since it allows to detect many errors during the compilation process. I've read, though, that in SBCL declarations are simply assertions, which are checked at the runtime.

If so, how can one use static typing in Common Lisp?

Re: Using static typing in CL

Posted: Tue Nov 25, 2008 6:58 am
by xach
The assertions inform the type inference, and you will usually get compile-time warnings for code that violates type declarations.

Re: Using static typing in CL

Posted: Tue Nov 25, 2008 7:49 am
by qbg
xach wrote:The assertions inform the type inference, and you will usually get compile-time warnings for code that violates type declarations.
Two small examples:

Code: Select all

* (defun foo (x)
(if (numberp x)
(car x)
x))
; in: LAMBDA NIL
;     (CAR X)
;
; caught WARNING:
;   Asserted type LIST conflicts with derived type (VALUES NUMBER &OPTIONAL).
;   See also:
;     The SBCL Manual, Node "Handling of Types"
;
; compilation unit finished
;   caught 1 WARNING condition

FOO

Code: Select all

* (defun foo (x)
(declare (cons x))
(* x 2))
; in: LAMBDA NIL
;     (* X 2)
;
; caught WARNING:
;   Asserted type NUMBER conflicts with derived type (VALUES CONS &OPTIONAL).
;   See also:
;     The SBCL Manual, Node "Handling of Types"
;
; compilation unit finished
;   caught 1 WARNING condition

FOO
Of course, it is important to note that not all implementations do the type-inferencing that SBCL does.

Re: Using static typing in CL

Posted: Tue Nov 25, 2008 9:14 am
by findinglisp
TPJ wrote:Hello.

I'm new to Lisp. I've heard that it's possible to declare the type of variables in Lisp. I find declaring types very useful, since it allows to detect many errors during the compilation process. I've read, though, that in SBCL declarations are simply assertions, which are checked at the runtime.

If so, how can one use static typing in Common Lisp?
Not quite. Declarations are checked at compile-time as much as they can be and the compiler will generate an error if it finds a conflict. With multiple compilation modules, runtime code generation, etc., this cannot be a perfect net, however. Thus, type errors can still occur. (I'd note that with things like untyped pointers, this can occur even in static languages like C.)

So, to help deal with these situations gracefully, SBCL will insert runtime type checking code to confirm that particular types are as you have declared them. If you violate the typing, the checks will catch it and throw you into the debugger as punishment, but the Lisp image will still be up and stable and you can debug appropriately. This is done for standard levels of speed and safety. Now, if you tell the compiler that you want high speed and no safety, it will produce code that eliminates these checks and simply believes whatever you tell it, with the consequence of a crash if it turns out later that you lied. It's a tradeoff. For anything other than small inner loops, I wouldn't do this. I'd rather have the system running if I make a mistake in order to debug and you'll get far more speedup algorithmically than you will from eliminating type checking in most cases.

Re: Using static typing in CL

Posted: Sat Nov 29, 2008 8:11 am
by Neonsquare
findinglisp wrote:Not quite. Declarations are checked at compile-time as much as they can be and the compiler will generate an error if it finds a conflict. With multiple compilation modules, runtime code generation, etc., this cannot be a perfect net, however. Thus, type errors can still occur. (I'd note that with things like untyped pointers, this can occur even in static languages like C.)
This seems to be one of the biggest misunderstandings in the classical strong static typing camps. The conservative view is that compilation is always a phase before the program is run. A program - once compiled - cannot change in unforeseen ways. I've discussed this topic extensively with guys seeing themselves as field experts - it really doesn't seem to click in.

The strict order of lifetime phases of a program are less strict in common lisp. It is easy to create programs that compile or load things within the running program. One consequence of this is that obvious bugs could be fixed through code build or loaded at runtime. So if you compile a common lisp function like this:

Code: Select all

(defun foo (a)
  (if (numberp a)
      (car a))
or

Code: Select all

(defun bar (a)
  (declare (cons a))
  (1+ a))
The result has to be a valid common lisp program. All common lisp systems should produce a program you can start. It always can be that the above functions would be used like this:

Code: Select all

(defun baz ()
  (handler-case (bar (cons 1 2)) (error () 'done)))
For the hardcore conservativists in the static types field this means that nothing is safe. The reality is actually quite different: A good common lisp implementation has all information set to issue a warning. The simple consequence is that a common lisp programmer should have an even bigger eye on issued warnings: A good rule of thumb is that a warning in common lisp is often a sign for a bug that could cancel compilation in more strict and conservative static languages; it's a clear signal that one should re-check the code. Non-critical warnings are issued as "style warnings" in common lisp.

To me - this property of common lisp makes it actually more robust and more safe than the brittle compile once crash everywhere attitude of other systems.

ciao,
Jochen Schmidt

--
Jochen Schmidt
CRISPYLOGICS
Uhlandstr. 9, 90408 Nuremberg

Fon +49 (0)911 517 999 82
Fax +49 (0)911 517 999 83

mailto:(format nil "~(~36r@~36r.~36r~)" 870180 1680085828711918828 16438) http://www.crispylogics.com

Re: Using static typing in CL

Posted: Mon Dec 01, 2008 1:34 pm
by findinglisp
Neonsquare wrote: ...<<good stuff snipped>>...
To me - this property of common lisp makes it actually more robust and more safe than the brittle compile once crash everywhere attitude of other systems.
Well said.