La cosa es que ... defmethod necesita que sea una clase, no una estructura, estructuras en elisp son vectores. Tal vez podría idear su propio método de despacho genérico, pero probablemente usar clases en lugar de estructuras lo resolverá: las clases se implementan en eieio.el, por lo que puede ver el interior y ver cómo lo envían. O simplemente podría tener algo como:
(defun foo (monster)
(cond
((eql (aref monster 0) 'cl-orc-struct) ...) ; this is an orc
((eql (aref mosnter 0) 'cl-elf-struct) ...) ; this is an elf
(t (error "Not a mythological creature"))))
Sería realmente dependerá del número de clases de criaturas están allí, probablemente usted podría llegar a algún macro que oculta la condición o bien devuelve la función de llamada según la etiqueta de tipo, etc.
A continuación, se presenta una idea simplificada para crear sus propios genéricos, en caso de que quiera seguir con las estructuras y no necesite mucha funcionalidad o si lo hace por su cuenta:
(defvar *struct-dispatch-table* (make-hash-table))
(defun store-stuct-method (tag method definition)
(let ((sub-hash
(or (gethash method *struct-dispatch-table*)
(setf (gethash method *struct-dispatch-table*)
(make-hash-table)))))
(setf (gethash tag sub-hash) definition)))
(defun retrieve-struct-method (tag method)
(gethash tag (gethash method *struct-dispatch-table*)))
(defmacro define-struct-generic (tag name arguments)
(let ((argvals (cons (caar arguments) (cdr arguments))))
`(defun ,name ,argvals
(funcall (retrieve-struct-method ',tag ',name) ,@argvals))))
(defmacro define-struct-method (name arguments &rest body)
(let* ((tag (cadar arguments))
(argvals (cons (caar arguments) (cdr arguments)))
(generic))
(if (fboundp name) (setq generic name)
(setq generic
`(define-struct-generic
,tag ,name ,arguments)))
(store-stuct-method
tag name
`(lambda ,argvals ,@body)) generic))
(define-struct-method test-method ((a b) c d)
(message "%s, %d" a (+ c d)))
(test-method 'b 2 3)
"b, 5"
Gracias, comprobaré defclass. – louxiu