Design by contract (2)
dbc.lisp をほんの少しだけ使ってみた。※以下の例はいまいち。
;; stack pop (defgeneric stack-pop (st) (:method-combination dbc)) ;; pop の本体 (defmethod stack-pop ((st stack)) (vector-pop (items st))) ;; 事前条件 スタックは空でないこと。スタックが空なのに pop を呼び出したら呼び出した側の責任。 (defmethod stack-pop :precondition ((st stack)) (not (stack-empty st)))
不変条件は、定義しておけば、自動的にメソッドの呼び出し前後に実行される。
現時点での感想。
もちろんフレームワーク無しでもやれることだが、徹底してくれるのが嬉しい。本体はシンプルに、事前事後条件は明確に分離して書ける、のは奇麗だ。教科書にのってるような簡潔さを保ちつつ、実際は業務のプログラムのように泥臭くチェックをしている。
- つまらないバグを減らしてくれるとは期待できる。
ただ、かなり意識的に条件を書けないと無意味。
- 強い型の言語の型も契約の一種?
- でも結局ランタイムでのエラーチェックでしかないのだろうか?
後でもうちょっと良い例を考える。