戻り値の型宣言 - lisp-cookbook-ja/common-lisp GitHub Wiki

戻り値に型を宣言することにより、コンパイル時や、実行時に型チェックをすることが可能です。

※ただし、仕様では型宣言自体、処理系によっては無視しても問題ありませんので、移植性が重要な問題になる場合には別の方法を検討する必要もあるでしょう。

return-integer は任意の型の引数を一つ受取りintegerを返すという宣言をした場合

(declaim (ftype (function (t) integer) return-integer))

(defun return-integer (obj)
  'foo)
; 整合性がない場合、警告を出してくれる処理系もある
; caught STYLE-WARNING:
;   The result type from proclamation:
;     (VALUES INTEGER &REST T)
;   conflicts with the definition's result type:
;     (VALUES (MEMBER FOO) &OPTIONAL)

(defun return-integer (obj)
  obj)

(return-integer 'foo)
;>>> The value FOO is not of type INTEGER. (処理系依存)

theを用いての直接的な指定

(defun return-list (obj)
  (the list obj))

(return-list 'foo)
;>>> The value FOO is not of type LIST. (処理系依存)

;;; 処理系拡張でvaluesが使える場合もある
(defun return-vector (obj)
  (declare (values vector))
  obj)

(return-vector 'foo)
;>>> The value FOO is not of type VECTOR.

多値の場合

(declaim (ftype (function (t) (values list integer)) return-list-and-integer))

(defun return-list-and-integer (obj)
  (values obj (car obj)))

;; もしくは、theにより直接指定
(defun return-list-and-integer2 (obj)
  (the (values list integer)
    (values obj (car obj))))

(return-list-and-integer (list 1))
;=>  (1)
;    1

(return-list-and-integer '(foo))
;>>> The value FOO is not of type INTEGER. (処理系依存)

議論