|
|
|
|
|
by muflax
3691 days ago
|
|
How does static type checking work in CL? One of the most important use cases for static typing is safe modification of existing code, like during refactoring. So a typical example: I have some struct with a field of one type, say a string. I use it in a few functions, reading and writing it. Now I change the field to a different type, say an array of strings instead. I want the compiler to tell me about all the code that's now invalid. How do I do that? I quickly wrote up a simple example of the (statically) untyped code I mentioned: http://pastebin.com/f7KWETvT (I can also write a matching example in some common static language (like C or ML), but I think it's clear what I mean.) What type annotations do I add to make that basic use case work? So what do I add such that it first type-checks when name is just a string, then change the annotation to make name an array of strings, and get two compile-time errors because the functions are now wrong. (Unfortunately, I only know a little bit of CL (and even then mostly due to familiarity with Emacs Lisp), so my example might be a bit un-idiomatic. Feel free to turn it into idiomatic CL if something is too weird!) |
|
(defstruct person (age 0 :type fixnum) (name "" :type string))
Now every access to that person structure should be checked by the compiler. You can create a person like:
(setf p (make-person :age 7 :name "fred")) => #S(PERSON :AGE 7 :NAME "fred")
But not with: (setf p (make-person :age 7 :name 8))
which causes SBCL to error with: The value 8 is not of type STRING. [Condition of type TYPE-ERROR]
Equally, if you tried wrongly to define
(defun print-hello (person) (let ((name (string-upcase (person-age person)))) (format t "Hallo ~a!~%" name)))
You get at least a warning you should heed: ; caught WARNING: ; Asserted type (OR (VECTOR CHARACTER) (VECTOR NIL) BASE-STRING SYMBOL CHARACTER) ; conflicts with derived type (VALUES FIXNUM &OPTIONAL).
So, for refactoring, you would change the type signatures of your struct and then recompile all code to see whether the compiler generates errors/warnings.