Распространенные объявления типов Lisp не работают должным образом - PullRequest
5 голосов
/ 01 марта 2012

Когда я определяю функцию в Common Lisp следующим образом:

(defun foo (n)
  (declare (type fixnum n))
  (+ n 42))

Я ожидал, что вызов типа (foo "a") сразу прервется, но вместо этого произойдет сбой при вызове +. Форма declare не гарантирует статическую проверку типов?

Ответы [ 2 ]

14 голосов
/ 01 марта 2012

Объявления типов традиционно предназначены для использования в качестве гарантий компилятору в целях оптимизации.Для проверки типа используйте check-type (но обратите внимание, что она также выполняет проверку во время выполнения, а не во время компиляции):

(defun foo (n)
  (check-type n fixnum)
  (+ n 42))

Тем не менее, различные реализации Common Lisp интерпретируют объявления типовпо-другому.SBCL, например, будет рассматривать их как проверяемые типы , если параметр политики safety достаточно высок.

Кроме того, если вы хотите статическую проверку, SBCL, вероятно, ваш лучшийСтавка также, так как его механизм вывода типов предупреждает вас о любых несоответствиях, с которыми он сталкивается.Для этого можно использовать ftype объявлений:

CL-USER(1): (declaim (ftype (function (string) string) bar))

CL-USER(2): (defun foo (n)
              (declare (type fixnum n))
              (bar n))
; in: DEFUN FOO
;     (BAR N)
; 
; caught WARNING:
;   Derived type of N is
;     (VALUES FIXNUM &OPTIONAL),
;   conflicting with its asserted type
;     STRING.
;   See also:
;     The SBCL Manual, Node "Handling of Types"
; 
; compilation unit finished
;   caught 1 WARNING condition

FOO
0 голосов
/ 01 марта 2012

Объявления - это просто подсказки компилятору, чтобы он мог создавать более эффективный код. Другими словами, это не статическая проверка.

...