Comprehensive guide on common lisp types

前端 未结 3 483
甜味超标
甜味超标 2021-01-19 04:41

Maybe this question is too general, nevertheless i\'ll try: Is there any comprehensive guide on types in common lisp?

I\'m kind of confused about this subject:

3条回答
  •  爱一瞬间的悲伤
    2021-01-19 05:37

    You need to tell the compiler to optimize for safety if you want it to actually enforce the types:

    CL-USER> (declaim (optimize (safety 3)))
    NIL
    CL-USER> (defclass foobar () ())
    #
    CL-USER> (defun foo (a)
               (make-array 1 :element-type 'foobar
                             :initial-contents (list a)))
    FOO
    CL-USER> (foo (make-instance 'foobar))
    #(#)
    CL-USER> (foo 12)
    ;=> ERROR
    CL-USER> (declaim (ftype (function (integer integer) integer) quux))
    (QUUX)
    CL-USER> (defun quux (a b)
               (+ a b))
    QUUX
    CL-USER> (quux 12 12)
    24 (5 bits, #x18, #o30, #b11000)
    CL-USER> (quux 12 "asd")
    ;=> ERROR
    

    Checking the types at run-time adds some overhead (especially if it happens in a loop), and may be done multiple times for a single value, so it's not done by default.

    (declaim (optimize (safety 3)))
    
    (defun some-predicate-p (a)
      (format t "~&Checking type...")
      (integerp a))
    
    (deftype foo () `(satisfies some-predicate-p))
    
    (defclass bar ()
      ((foo :type foo :initarg :foo)))
    
    (declaim (ftype (function (foo) list) qwerty))
    (defun qwerty (foo)
      (loop repeat 10 collecting (make-instance 'bar :foo foo)))
    
    (qwerty 12)
    ; Checking type...
    ; Checking type...
    ; Checking type...
    ; Checking type...
    ; Checking type...
    ; Checking type...
    ; Checking type...
    ; Checking type...
    ; Checking type...
    ; Checking type...
    ; Checking type...
    ;=> (# # #
    ;    # # #
    ;    # # #
    ;    #)
    

    If you want a function to always check the type of a place, regardless of the optimization settings, you should use CHECK-TYPE manually.

提交回复
热议问题