3

Common Lisp でマルチメソッドの「オーバーロード呼び出し」を行おうとしています。ケースの簡単な概要は次のとおりです。

(defclass foo ()
  ((slotty :accessor slotty :initarg :slotty)))

(defclass bar ()
  ((slotty :accessor slotty :initarg :slotty)))

(defparameter *foo* (make-instance 'foo :slotty "defnoodle"))
(defparameter *bar* (make-instance 'bar :slotty "Chocolate"))

(defmethod contrived ((f foo) (b bar))
  (format t "i pity the foo ~A, who has a bar ~A ~%" (slotty f) (slotty b)))

(contrived *foo* *bar*)

出力:i pity the foo defnoodle, who has a bar Chocolate

しかし、次のメソッドを定義しようとするとすぐに:

 (defmethod contrived ((f foo))
    (format  t "i just pity the foo ~A ~%" (slotty f)))

CLは怒る:

; The generic function #<STANDARD-GENERIC-FUNCTION CONTRIVED (1)>
; takes 2 required arguments; was asked to find a method with
; specializers (#<STANDARD-CLASS FOO>)
;   [Condition of type SB-PCL::FIND-METHOD-LENGTH-MISMATCH]
; See also:
;  Common Lisp Hyperspec, FIND-METHOD [:function]

ここで私が間違っていることを誰かが知っていますか? クラスごと、任意の数の引数ごとにn個のinitialize-instanceメソッドを識別できるはずなので、initialize-instanceにも同様の柔軟性があることを私は知っています。

(defmethod initialize-instance :after ((f foo) &key)
  ())

しかし、これを上記のバニラの例にどのように翻訳できるかは明確ではありません。そして、これは MOP の一部であるため、間違ったツリーを吠えている可能性があるように感じます。

4

2 に答える 2

7

あなたは次のように書いています。

明確にするために:CLOSはそれをサポートしていません。1 つのジェネリック関数のメソッドのメソッド パラメーター リストに異なる数の必須引数を含めることはできません。ディスパッチは、必要な引数に対してのみ機能します。Common Lisp は「オーバーロード」をサポートしていません。

INITIALIZE-INSTANCEは次の構文で定義されます。

initialize-instance instance &rest initargs &key &allow-other-keys => instance

すべてのメソッドは、インスタンスという 1 つの必須引数を取ります。ディスパッチは、このオブジェクトに対してのみ行われます。次に、さまざまなキーワード引数を許可します - それらのディスパッチは行われません。

したがって、ジェネリック関数が取る必要のある引数の数に同意し、コードでそのように呼び出す必要があります。

ルールについては CL Hyperspec を参照してください: Congruent Lambda-lists for all Methods of a Generic Function

于 2014-02-20T07:47:00.050 に答える