2016-04-04 14 views
7

私はプログラマーが機械に単に型を定義するという、タイプリッチプログラミングと呼ばれる興味深い概念を記述した静的型付けについての記事を読む(https://bsamuels.net/2013/11/20/static-typing.html)。整数や浮動小数点数など)がありますが、これらのマシンタイプを使用して表現できる量の違いを説明しています(秒とメートルの両方を二重で表すこともできますが、Common Lispの豊富なプログラミング?

私は、Common Lispは動的に型定義された言語であることを知っています。しかし、私はthecheck-typeを使用すると、いくつかのコンパイラ(私が使用するもの、SBCLなど)が制限付き型チェックを行うことも知っています。タイプエイリアスを作成して、より豊富なタイプをSBCLに提供する方法はありますか?そうでなければ、Common Lispでタイプ豊富なプログラミングのように見えるものはどうすれば手に入りますか?

+0

Gordon S. Novak Jr.の「測定単位の変換」(https://www.cs.utexas.edu/users/novak/units95.html)を参照してください。 – coredump

答えて

5

Common Lispには新しいタイプを定義するためのDEFTYPEがあります。たとえば:

(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 #\.))) 

これは、しかし、一緒秒とメートルを追加するのを防ぐことはできません:

(deftype meters() 
    'number) 

(let ((s 30) 
     (m 15)) 
    (declare (type seconds s) 
      (type meters m)) 
    (+ s m)) 
;=> 45 

あなたは値が有効なものであることを確認するために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)) 

ただし、値が有効であることを確認するだけです。関数が値を渡すだけなので、変数をメートルと宣言しても気にしません。

(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 

秒とメーターが一緒に追加されないようにするには、クラスとオブジェクトを使用するだけです。

関連する問題