While reading about CLOS (in ANSI Common Lisp by Paul Graham), I noticed that there are nine functions that can be given to defmethod as its second argument:
+, and, append, list, max, min, nconc, or and progn. According to this answer, they are called simple method combinations.
Question
Why only these nine? What is the reason I cannot pass an arbitrary function as the second argument?
Example of what I would like
Suppose I defined xor as
(defun xor (&rest args)
(loop for a in args counting (not (null a)) into truths
finally (return (= truths 1))))
(this could certainly be improved). I would like to define several classes describing clothes and their combinations using xor:
(defgeneric looks-cool (x)
(:method-combination xor))
(defclass black-trousers () ())
(defclass quilt () ())
(defclass white-shirt () ())
(defclass hawaii-shirt () ())
(defmethod looks-cool xor ((tr black-trousers)) nil)
(defmethod looks-cool xor ((qu quilt)) t)
(defmethod looks-cool xor ((ws white-shirt)) nil)
(defmethod looks-cool xor ((hs hawaii-shirt)) t)
(defclass too-stiff (black-trousers white-shirt) ())
(defclass scottish (quilt white-shirt) ())
(defclass also-good (black-trousers hawaii-shirt) ())
(defclass too-crazy (quilt hawaii-shirt) ())
Now if this compiled (which it doesn't), I would be able to use Lisp to guide me as to what to wear:
> (looks-cool (make-instance 'too-stiff))
NIL
> (looks-cool (make-instance 'scottish))
T
> (looks-cool (make-instance 'also-good))
T
> (looks-cool (make-instance 'too-crazy))
NIL
I am well aware that this is a rather artificial example of no practical importance. Still, I would like to know whether there is some deeper reason behind or whether the restriction to the nine functions is just to make implementation easier.
Use the standard Common Lisp macro DEFINE-METHOD-COMBINATION to define your own simple method combinations:
Example:
Then:
If we look at
(define-method-combination xor :identity-with-one-argument t), it has several meanings for the namexor:it uses an operator
xor- a function, macro or special form - not only functions are allowed. If the operator name should be different from the method combination name -> use the:operatorkeyword to specify that.it defines a method combination named
xor. This name can be used indefgeneric.it defines a method qualifier
xor. This can be used indefmethod.Note that one can also define more complex method combinations with that
DEFINE-METHOD-COMBINATION.