4 ms·
First of all, you have modified the function that I posted (you changed the type declaration from a list to an array). Second, you do not read your compiler wa
by jgrant27 17y ago
First of all, you have modified the function that I posted (you changed the type declaration from a list to an array).
Second, you do not read your compiler warning messages.
SBCL is trying to tell you that you shouldn't type something as an array when you are clearly attempting to use it as a list e.g. calling the CAR function on an array makes no sense. A list and an array in Lisp are not the same. The CAR function in Lisp only works on lists.
* (defun foo (x) (declare (type array x)) (car x))
; in: LAMBDA NIL
; (CAR X)
;
; caught WARNING:
; Asserted type LIST conflicts with derived type (VALUES ARRAY &OPTIONAL).
; See also:
; The SBCL Manual, Node "Handling of Types"
It's correctly warning you before you even try and call the foo function, because it will fail no matter what you pass to it !
- gwern 17y ago> First of all, you have modified the function that I posted (you changed the type declaration from a list to an array). How would I demonstrate SBCL's ability to detect type errors except by making a type error? Your example showed nothing; 'type' could be a null-op for all it does. And checks about primitive types are all well and good, but how far does it go? Not being much of a lisper, it's hard for me to give whole classes of example where SBCL's warnings are non-existent, incorrect, or buried under a flurry of others. If I declare a custom CLOS object with multiple fields/methods/whatever and call a field/method which doesn't exist, is SBCL still smart enough to warn me? I dunno.
- jgrant27 17y agoThere is no concept of a 'primitive' type in Common Lisp. It handles type-checking for built-in types or for your own custom declared types. CL's type system is very powerful. Here's a type-checking example related to CLOS : ;; High safety settings are required by SBCL for type checking of slots ;; See --> http://www.apl.jhu.edu/~hall/Lisp-Notes/Defclass.html (declaim (optimize (speed 0) (compilation-speed 0) (safety 3) (debug 3))) (defclass circle() ((center :type cons :accessor circle-center :initarg :center) (radius :type fixnum :accessor circle-radius :initarg :radius))) (defmethod circle-area ((x circle)) (* pi (expt (circle-radius x) 2))) (let ((c (make-instance 'circle :center '(0 0) :radius 4))) (format t "~A~%" (circle-area c)) (setf (circle-center c) '(2 3)) (setf (circle-radius c) 7) ;; this will fail at compile with a TYPE-ERROR ;(setf (circle-radius c) "B") ;; this will fail at compile with a UNDEFINED-FUNCTION ;; because the method does not exist ;(location c) )
- gwern 17y ago> (let ((c (make-instance 'circle :center '(0 0) :radius 4))) ... Erm, what? This is supposed to show smart compile-time checking about runtime behavior?? This no more demonstrates what you apparently think it demonstrates than I could demonstrate Haskell's type-soundness by taking some Template Haskell, inserting 'head []', and saying 'it crashes during compilation, eureka!' What would be fairer would be wrapping all that in a '(defun foo () )', in which case one doesn't get any warning relating to the 'location c' or "B": * (load "foo.cl") STYLE-WARNING: Implicitly creating new generic function CIRCLE-AREA. ; in: LAMBDA NIL ; ((LET ((C (MAKE-INSTANCE 'CIRCLE :CENTER '# :RADIUS 4))) ; (FORMAT T "~A~%" (CIRCLE-AREA C)) ; (SETF (CIRCLE-CENTER C) '(2 3)) ; (SETF (CIRCLE-RADIUS C) 7) ; (SETF (CIRCLE-RADIUS C) "B") ; (LOCATION C))) ; ; caught ERROR: ; illegal function call ; ; compilation unit finished ; caught 1 ERROR condition T
- deleted 17y ago[deleted]
- jgrant27 17y agoIt's runtime checking. I really don't care though. Common Lisp just has a different approach, it sits between static typing and dynamic typing. It's type declarations are for optimization. Which I see as the main benefit anyway. Besides, I've been around long enough to have seen applications that were implemented using statically-typed languages, simply explode. Static typing, IMHO, is extremely overrated. Since many statically typed languages make it easy to cast one type into another, you can't trust it to be anything more than an optimization hint. This been quite the diversion(thanks). I'm mainly interested in meta-programming in Haskell & how it compares with Lisp.