Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

In regards to Common Lisp, depending on which implementation you use you may get some sort of type checking at compile time.

For example, if you save the following code[1] into a file and try to load it into SBCL, it will give a compile time error:

    (ql:quickload 'defstar)
    
    (use-package 'defstar)
    
    (declaim (optimize (debug 3) (speed 0) (safety 3)))
    
    (defun* factorial ((x (integer 0 *))) ;; x is an integer from 0 up to +inf
      (if (zerop x)
          1
        (* x (factorial (1- x)))))
    
    (defun main ()
      (factorial "foo")  ;; Compile time error: "foo" conflicts with its assert type UNSIGNED-BTYE
      (factorial -1)     ;; Compile time error: -1 conflicts with its assert type UNSIGNED-BTYE
      (factorial 1.0)    ;; Compile time error: 1.0 conflicts with its assert type UNSIGNED-BTYE
      (factorial 0))     ;; Works

And when you load the file into SBCL you get the following error message (assuming you have Quicklisp installed):

    $ sbcl --load compile-time-safety.lisp 
    This is SBCL 1.2.7, an implementation of ANSI Common Lisp.
    More information about SBCL is available at <http://www.sbcl.org/>.
    
    SBCL is free software, provided as is, with absolutely no warranty.
    It is mostly in the public domain; some portions are provided under
    BSD-style licenses.  See the CREDITS and COPYING files in the
    distribution for more information.
    To load "defstar":
      Load 1 ASDF system:
        defstar
    ; Loading "defstar"
    
    
    ; file: /home/rol/src/lisp/compile-time-safety.lisp
    ; in: DEFUN MAIN
    ;     (FACTORIAL "foo")
    ; 
    ; caught WARNING:
    ;   Constant "foo" conflicts with its asserted type UNSIGNED-BYTE.
    ;   See also:
    ;     The SBCL Manual, Node "Handling of Types"
    ; 
    ; compilation unit finished
    ;   caught 1 WARNING condition

It's not as nice as Haskell's type system, but it's something :)

The main problem with this sort of compile-time checking is that it's implementation dependent, so some Common Lisp implementation may not provide it. You can configure the defstar library that I used on this code so that it automatically adds calls to "(check-type ...)". But then you are back at doing run-time checking of types.

--

[1] - The defstar library can be found on Quicklisp or here: https://bitbucket.org/eeeickythump/defstar/

It's pretty much just a nicer way to write all of the "(declaim ...)" and "(declare ...)" needed to provide the most information to the Common Lisp type system.



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: