Difference between standard lisp and emacs lisp

The code below uses generic lisp, but in emacs lisp it complains "(error" Unknown type of type orc in method parameters ")". Why and how can I fix this in emacs lisp? Thank.

(defun randval (n)
  (1+ (random (max 1 n))))

(defstruct monster (health (randval 10)))

(defstruct (orc (:include monster)) (club-level (randval 8)))

(defmethod monster-show ((m orc))
  (princ "A wicked orc with a level ")
  (princ (orc-club-level m))
  (princ " club"))
+5
source share
1 answer

The thing is that defmethod needs to be a class, not a structure, a struct in eLisp is just vectors. Perhaps you could come up with your own dispatch method, but maybe just using classes, not structures, it will decide - the classes are embedded in eieio.el, so you can look at its insides and see how they are dispatched. Or you could just have something like:

(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"))))

, , , - , , , ..

, , , :

(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"
+3

All Articles