CLOS
を読んでいますが、ちょうどCLOSの説明のところを読んでいて、軽い衝撃を受けています。
なんていうか、私の知っているオブジェクト指向とは違いすぎるというか・・・
詳細な文法は省くとして、衝撃を受けたポイントを端的に言うと、クラスとメソッドの結合がゆるいのです。
メソッドは、もはや「メッセージ」という比喩は使えず、「総称関数」と呼ばれます。
オブジェクトが自分のメソッドを知っているというよりも、メソッドが受け取ったオブジェクトの種類を判断して、呼び出すメソッドを選びます。メソッドが判断するので、こんなメソッドも作れます。
(defmethod combine ((x (eql 'powder)) (y (eql 'spark))) 'boom)
eqlは等値を判断する関数ですので、比較して一致するものだけに適用されるメソッドが作成されます。(よく考えると、これは、Rubyの特異メソッドに似ているといえるかも知れません。)
メソッドコンビネーションというのもあり、これは、
(defgeneric price (x) (:method-combination +)) (defmethod price + ((jk jacket)) 350) (defmethod price + ((tr trousers)) 200) (defclass suit (jacket trousers) ()) ;;実行結果は 550 = 350 + 200 (price (make-instance 'suit))
のように書き、スーパークラスの側にさかのぼって結果を足し算(+)するという機能です。