#:g1: method-combination-utilitiesの紹介

Posted 2014-02-05 15:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の37日目です。

method-combination-utilitiesとはなにか

 method-combination-utilitiesは、Greg Pfeil氏作のメソッドコンビネーションの定義などを簡便にできるようにするライブラリです。

パッケージ情報

パッケージ名method-combination-utilities
Quicklisp
参考サイト
Quickdocshttp://quickdocs.org/method-combination-utilities

インストール方法

(ql:quickload :method-combination-utilities)

試してみる

 どんな関数があるかは、Quickdocsで確認できます。

 quickdocsのドキュメントを読めば大体分かると思いますが、method-combination-utilitiesでは、4種のメソッドコンビネーションを提供しています。

PRIMARY
ISLISPには、プライマリのみというNILメソッドコンビネーションがあり、それを真似たもの。NILを使うとパッケージロックにひっかかるためPRIMARYという名前になっているとのこと。
LAX
qualifier-pattern部を緩くしたもの
(defgeneric maporfic (x)
  (:method-combination lax))

(defmethod maporfic foo bar baz ((n number)) :number)

(defmethod maporfic ((x symbol)) :symbol)

(maporfic 8) ;=> :NUMBER (maporfic 'z) ;=> :SYMBOL

のように任意のパターンを書くことができるので、あとは必要に応じて色々処理をするのでしょう。
BASIC
define-method-combinationには短形式というものがありますが、実際に使われているのを目にしたことがない、ということで、basic+オペレーターという形に纏めてしまおう、というアイデアです。
(defclass superclass () ())
(defclass subclass (superclass) ())

(defun plus (&rest args) (apply #'+ args))

(defgeneric badios (object) (:method-combination basic plus) (:method plus ((object superclass)) 1) (:method plus ((object subclass)) 2))

(badios (make-instance 'subclass)) ;=> 3

という風にdefine-method-combinationでの定義なしに使えます。
とりあえず利用にあたっては、basicの定義の
(primary (*) :order order :required t)
という記述ではSBCLでは動かないので
(primary * :order order :required t)
と修正。(primary (*))という記述はありなのでしょうか。
APPEND/NCONC
必要に応じてNCONCになってくれるというもの

開発時に便利なユーティリティ: method-combination-expand

 メソッドコンビネーションでメソッドがどういう風に呼び出されるのか確認したいことがありますが、実行メソッドの展開形を表示してくれるユーティリティです。

(method-combination-expand (badios (make-instance 'subclass)))
;=>  (PLUS (CALL-METHOD #<STANDARD-METHOD BADIOS PLUS (SUBCLASS) {1022B2DB83}>)
;          (CALL-METHOD #<STANDARD-METHOD BADIOS PLUS (SUPERCLASS) {1022B2F523}>))

compute-effective-methodを手書きするのも面倒なので便利です。
その他、call-methodを纏めるcall-methods等、定義では定番のものもユーティリティとして含まれています。

まとめ

 今回は、method-combination-utilitiesを紹介してみました。
メソッドコンビネーション自体が非常にマイナーなところで資料も少ないと思います。
実際define-method-combinationの動作も難解なためか、CLtL2のコードを丸ごとコピペしたようなコードも良くありますが、その辺りを上手く纏めているかなと思いました。
メソッドコンビネーションで何かする場合には、眺めてみると非常に参考になるのではないでしょうか。

comments powered by Disqus