Lispで契約プログラミングを実現した例があるのでこれを眺めつつ、マクロで色々やっているところをMOPを使うようにしてみたいと思います。Meyer氏のEiffelにインスパイアされて作ったものです。Contractdbc.lispの構成まず、dbc.lispでは、エラー時に発生させるコンディションが細かく定義されています。次に、不変条件、事前/事後条件のチェックの差し込みにCLOSのメソッドコンビネーションを利用します。メソッドコンビネーションのカスタマイズもMOPに触るところではあるのですが、CLの場合、define-method-combinationで定義するので、直接触っている感じではありません。それぞれのメソッドは、同じものが集められいて、どんな風にcall-methodで実行されるかが記述されています。これが、compute-effective-methodに渡されて合体されます。使い、クラスのライタとリーダにそれぞれ、:invariantメソッドを付加することによって読み書き時に実行されるようになっています。これに加えて、make-instanceでもcheck-invariantが実行されるようにしてあります。これらは、どういう風にして定義されるかというと、基本的にマクロで上記のメソッドのコードが生成されるようになっています。object))defclassとmake-instanceが置き換えられていて、defclassではメソッドの定義がずらっと並ぶようになっています。MOPを使って書き直してみよう標準のdefclassとmake-instanceを置き換えるのは名前の衝突等を考えるとあまり嬉しくないので、ここはMOPでメソッドを追加するようにしてみよう、ということで書いたのが下記です。dbc)時にメソッドを定義するようにしています。null)を変更するのは、なんか気持ち悪い気がしますが、他に方法はあるのでしょうか。一応dbcの時だけ反応するようにしていますが、もっと良い方がある気がします。それとメソッドを生成するフォームがdefmethodを利用しているため、これも気持ち悪いことになっています。これも改善したいところ。make-instanceは、dbcメタクラスで不変条件をチェックするように変更。実行してみるCLを使っている人以外には実感しづらいですがCLパッケージをそのままuseできているところが改善点です。オリジナルでは、:metaclassの指定はありませんが、改変版は必要になります。ここが、めんどくさいといえば、めんどくさいところです。4チェック通過まとめもっと綺麗に書けると良かったのですが、小汚くなりました。不変条件は、スロットごとメソッドを付ける位なら、指定もスロットごとにしてみても良いような気もします。