Types CommonLisp中的类型丰富编程?

Types CommonLisp中的类型丰富编程?,types,common-lisp,Types,Common Lisp,前几天我读了一篇关于静态类型的文章(),其中描述了一个有趣的概念,称为“类型丰富编程”,在这个概念中,作为程序员,您定义的类型对于机器来说只是现有类型的别名(例如整数或浮点数),但对于您来说,它们描述了使用这些机器类型可以表示的不同数量之间的差异(例如,秒和米都可以用双精度表示,但您肯定不想将它们相加) 我知道CommonLisp是一种动态类型语言。但是,我也知道,如果我使用the和check type,一些编译器(比如我使用的SBCL)将执行一些有限的类型检查。如何创建类型别名,以便为SBCL

前几天我读了一篇关于静态类型的文章(),其中描述了一个有趣的概念,称为“类型丰富编程”,在这个概念中,作为程序员,您定义的类型对于机器来说只是现有类型的别名(例如整数或浮点数),但对于您来说,它们描述了使用这些机器类型可以表示的不同数量之间的差异(例如,秒和米都可以用双精度表示,但您肯定不想将它们相加)

我知道CommonLisp是一种动态类型语言。但是,我也知道,如果我使用
the
check type
,一些编译器(比如我使用的SBCL)将执行一些有限的类型检查。如何创建类型别名,以便为SBCL提供更丰富的类型?或者,如果不是这样的话,那么我怎样才能得到类似于Common Lisp中类型丰富编程的东西呢?

Common Lisp有定义新类型的功能。例如:

(defun secondsp (s)
  (<= 0 s 59))
(deftype seconds ()
  '(and number (satisfies secondsp)))

(let ((s 0))
  (declare (type seconds s))
  (loop
     repeat 60 ;should cause an error when S becomes 60
     do (incf s)
     do (write-char #\.)))
您可以创建一个函数,该函数使用
CHECK-TYPE
或声明来检查值是否为有效值,持续数秒:

;; with CHECK-TYPE and THE
(defun add-seconds (s1 s2)
  (check-type s1 seconds)
  (check-type s2 seconds)
  (the seconds (+ s1 s2)))

;; With declarations
(declaim (ftype (function (seconds seconds) seconds) add-seconds-decl))
(defun add-seconds-decl (s1 s2)
  (+ s1 s2))
但这只会检查该值是否有效。它不在乎是否将变量声明为meters,因为函数只传递值

(let ((s1 30)
      (s2 15)
      (m 25))
  (declare (type seconds s1 s2)
           (type meters m))
  (format t "~&S1 + S2 = ~a" (add-seconds-decl s1 s2))
  (format t "~&S1 + M = ~a" (add-seconds-decl s1 m)))
;; S1 + S2 = 45
;; S1 + M = 55
如果你想强制执行秒数和米数不能相加,你应该只使用类和对象。

见Gordon S.Novak Jr。
(let ((s1 30)
      (s2 15)
      (m 25))
  (declare (type seconds s1 s2)
           (type meters m))
  (format t "~&S1 + S2 = ~a" (add-seconds-decl s1 s2))
  (format t "~&S1 + M = ~a" (add-seconds-decl s1 m)))
;; S1 + S2 = 45
;; S1 + M = 55