Я пытаюсь выполнить «перегрузочный вызов» многоточия в Common Lisp. Вот упрощенная изношенном корпуса:«Перегрузка» CLOS-мультиметодов с различными списками параметров
(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]
Кто-нибудь знает, что я делаю неправильно здесь? Я знаю, что initialize-instance имеет подобную гибкость, поскольку нужно иметь возможность идентифицировать n количество методов initialize-instance для каждого класса и для любого количества аргументов.
(defmethod initialize-instance :after ((f foo) &key)
())
, но мне непонятно, как я могу перевести это на пример ванили, который я дал выше. И я чувствую, что могу лаять неправильное дерево, так как это часть СС.
Это не перегрузка. Перегрузка означает раннее (компиляция) время привязки символов с тем же именем. То, что делает CLOS, - это _dispatch_, то есть поздняя (временная) привязка. Если у вас есть другое количество аргументов, нет необходимости откладывать это на время выполнения. Ограничение состоит в том, что у вас не может быть более одной общей функции с одним и тем же полным именем. – Svante