1;; -*- Lisp -*- vim:filetype=lisp
2
3#-(or GCL CMU SBCL OpenMCL LISPWORKS)
4(use-package "CLOS")
5#-(or GCL CMU SBCL OpenMCL LISPWORKS)
6T
7
8(unintern '<C1>)
9T
10
11(progn
12(defclass <C1> ()
13  ((x :initform 0 :accessor x-val :reader get-x :writer set-x :initarg :x)
14   (y :initform 1 :accessor y-val :reader get-y :writer set-y :initarg :y)))
15())
16NIL
17
18(progn
19(defclass <C2> (<C1>)
20  ((z :initform 0 :accessor z-val :reader get-z :writer set-z :initarg :z)))
21())
22NIL
23
24(defparameter a (make-instance (find-class '<C1>) :x 10))
25A
26
27(let (cache)
28  (defmethod slot-missing ((class t) (obj <C1>)
29                           (slot-name t) (operation t)
30                           &optional (new-value nil new-value-p))
31    (setf cache
32          (list slot-name operation new-value new-value-p)))
33  (list (slot-boundp a 'abcd) cache
34        (slot-value a 'abcd) cache))
35(#+(or ALLEGRO CMU18 OpenMCL LISPWORKS) (ABCD SLOT-BOUNDP NIL NIL) #-(or ALLEGRO CMU18 OpenMCL LISPWORKS) T
36 (ABCD SLOT-BOUNDP NIL NIL) (ABCD SLOT-VALUE NIL NIL) (ABCD SLOT-VALUE NIL NIL))
37
38(x-val a)
3910
40
41(y-val a)
421
43
44(setf (x-val a) 20)
4520
46
47(x-val a)
4820
49
50(get-x a)
5120
52
53(set-x 10 a)
5410
55
56(x-val a)
5710
58
59(with-slots (x y) a (+ x y))
6011
61
62(defun foo (z) (with-slots (x y) z (+ x y)))
63foo
64
65(foo a)
6611
67
68(compile 'foo)
69foo
70
71(foo a)
7211
73
74(symbol-cleanup 'foo) T
75
76(x-val (reinitialize-instance a :x 20))
7720
78
79(x-val (reinitialize-instance a :x 30))
8030
81
82(x-val (reinitialize-instance a :x 50))
8350
84
85(x-val (reinitialize-instance a :x 80))
8680
87
88(x-val (reinitialize-instance a :y 20))
8980
90
91(y-val (reinitialize-instance a :x 30))
9220
93
94(x-val (reinitialize-instance a :y 50))
9530
96
97(y-val (reinitialize-instance a :x 80))
9850
99
100(defparameter b (make-instance (find-class '<C2>) :x 10 :y 20 :z 30))
101B
102
103(x-val b)
10410
105
106(y-val b)
10720
108
109(z-val b)
11030
111
112(let* ((fn (defgeneric f (x y)
113             (:method ((x t) (y t))
114               (list x y))))
115       (meth1 (defmethod f ((i integer) (j number))
116                (+ i j)))
117       (meth2 (defmethod f ((s1 string) (s2 string))
118                (concatenate 'string s1 s2))))
119  (lambda () (defmethod f ((x list) (y list)) (append x y)))
120  (list (eq meth1 (find-method #'f nil (list (find-class 'integer)
121                                             (find-class 'number))))
122        (eq meth2 (find-method #'f nil (list (find-class 'string)
123                                             (find-class 'string))))))
124(T T)
125
126(f t t)
127(T T)
128
129(f 2 3)
1305
131
132(f 2 3.0)
1335.0
134
135(f 2.0 3)
136(2.0 3)
137
138(f "ab" "cd")
139"abcd"
140
141(f 1 "abc")
142(1 "abc")
143
144(progn
145(defgeneric f (x y)
146  (:method ((x t) (y t))
147    (list x y))
148  (:method ((i number) (j integer))
149    (list (call-next-method) (- i j)))
150  (:method ((i integer) (j number))
151    (list (call-next-method) (+ i j))))
152())
153NIL
154
155(f 'x 'y)
156(X Y)
157
158(f 1 2)
159(((1 2) -1) 3)
160
161(f 1 2.0)
162((1 2.0) 3.0)
163
164(f 1.0 2)
165((1.0 2) -1.0)
166
167(progn
168(defgeneric g (x)
169  (:method ((x null))
170    (cons 'null (call-next-method)))
171  (:method ((x list))
172    (if (next-method-p) (cons 'list (call-next-method)) '(list$)))
173  (:method ((x symbol))
174    (if (next-method-p) (cons 'symbol (call-next-method)) '(symbol$))))
175())
176NIL
177
178(g 'x)
179(SYMBOL$)
180
181(g '(x))
182(LIST$)
183
184(g '())
185(NULL SYMBOL LIST$)
186
187(defparameter *hl* nil)
188*HL*
189
190(progn
191(defgeneric hgen (x)
192  (:method ((x integer))
193    (setf *hl* (cons 'i-primary-1 *hl*))
194    (call-next-method)
195    (setf *hl* (cons 'i-primary-2 *hl*)))
196  (:method :before ((x integer))
197    (setf *hl* (cons 'i-before *hl*)))
198  (:method :after ((x integer))
199    (setf *hl* (cons 'i-after *hl*)))
200  (:method :around ((x integer))
201    (setf *hl* (cons 'i-around-1 *hl*))
202    (call-next-method)
203    (setf *hl* (cons 'i-around-2 *hl*)))
204  (:method ((x number))
205    (setf *hl* (cons 'n-primary-1 *hl*))
206    (call-next-method)
207    (setf *hl* (cons 'n-primary-2 *hl*)))
208  (:method :before ((x number))
209    (setf *hl* (cons 'n-before *hl*)))
210  (:method :after ((x number))
211    (setf *hl* (cons 'n-after *hl*)))
212  (:method :around ((x number))
213    (setf *hl* (cons 'n-around-1 *hl*))
214    (call-next-method)
215    (setf *hl* (cons 'n-around-2 *hl*)))
216  (:method ((x t))
217    (setf *hl* (cons 'innermost *hl*))))
218(defun h (x)
219  (setf *hl* '()) (hgen x) (reverse *hl*))
220)
221H
222
223(h 'abc)
224(INNERMOST)
225
226(h 3.14)
227(N-AROUND-1 N-BEFORE N-PRIMARY-1 INNERMOST N-PRIMARY-2 N-AFTER N-AROUND-2)
228
229(h 3)
230(I-AROUND-1 N-AROUND-1 I-BEFORE N-BEFORE I-PRIMARY-1 N-PRIMARY-1 INNERMOST
231  N-PRIMARY-2 I-PRIMARY-2 N-AFTER I-AFTER N-AROUND-2 I-AROUND-2
232)
233
234;; Keyword checking is enabled even when no method has &key.
235(progn
236  (defgeneric testgf00 (&rest args &key)
237    (:method (&rest args)))
238  (testgf00 'a 'b))
239ERROR
240
241;; Check that call-next-method functions have indefinite extent and can
242;; be called in arbitrary order.
243(let ((methods nil))
244  (defgeneric foo136 (mode object))
245  (defmethod foo136 (mode (object t))
246    (if (eq mode 'store)
247      (push #'call-next-method methods)
248      (if (eq mode 'list)
249        (list 't)
250        (cons (list 't) (funcall mode)))))
251  (defmethod foo136 (mode (object number))
252    (if (eq mode 'store)
253      (progn (push #'call-next-method methods) (call-next-method))
254      (if (eq mode 'list)
255        (cons 'number (call-next-method))
256        (cons (cons 'number (call-next-method 'list object)) (funcall mode)))))
257  (defmethod foo136 (mode (object real))
258    (if (eq mode 'store)
259      (progn (push #'call-next-method methods) (call-next-method))
260      (if (eq mode 'list)
261        (cons 'real (call-next-method))
262        (cons (cons 'real (call-next-method 'list object)) (funcall mode)))))
263  (defmethod foo136 (mode (object rational))
264    (if (eq mode 'store)
265      (progn (push #'call-next-method methods) (call-next-method))
266      (if (eq mode 'list)
267        (cons 'rational (call-next-method))
268        (cons (cons 'rational (call-next-method 'list object)) (funcall mode)))))
269  (defmethod foo136 (mode (object integer))
270    (if (eq mode 'store)
271      (progn (push #'call-next-method methods) (call-next-method))
272      (if (eq mode 'list)
273        (cons 'integer (call-next-method))
274        (cons (cons 'integer (call-next-method 'list object)) (funcall mode)))))
275  (foo136 'store 3)
276  (multiple-value-bind (t-error-method
277                        number-t-method
278                        real-number-method
279                        rational-real-method
280                        integer-rational-method)
281      (values-list methods)
282    (foo136 #'(lambda ()
283                (funcall number-t-method
284                  #'(lambda ()
285                      (funcall integer-rational-method
286                        #'(lambda ()
287                            (funcall real-number-method
288                              #'(lambda () nil)
289                              5))
290                        5))
291                  5))
292            5)))
293((INTEGER RATIONAL REAL NUMBER T)
294 (T)
295 (RATIONAL REAL NUMBER T)
296 (NUMBER T))
297
298(unintern '<C1>)
299T
300
301(progn
302(defclass <C1> ()
303  ((x :initform 0 :accessor x-val :initarg :x)
304   (y :initform 1 :accessor y-val :initarg :y)))
305())
306NIL
307
308(defparameter a (make-instance (find-class '<C1>) :x 10))
309A
310
311(defparameter b (make-instance (find-class '<C1>) :y 20 :x 10))
312B
313
314(defparameter c (make-instance (find-class '<C1>)))
315C
316
317(x-val a)
31810
319
320(y-val a)
3211
322
323(x-val b)
32410
325
326(y-val b)
32720
328
329(x-val c)
3300
331
332(y-val c)
3331
334
335(unintern '<C1>)
336T
337
338(let* ((c (defclass <C1> ()
339            ((x :initform 0 :accessor x-val :initarg :x)
340             (y :initform 1 :accessor y-val :initarg :y))))
341       (m (defmethod initialize-instance :after ((instance <C1>)
342                                                 &rest initvalues)
343            (if (= (x-val instance) 0)
344                (setf (x-val instance) (y-val instance))))))
345  (eq m (find-method #'initialize-instance '(:after) (list c))))
346T
347
348(x-val (make-instance (find-class '<C1>)))
3491
350
351(x-val (make-instance (find-class '<C1>) :x 10))
35210
353
354(x-val (make-instance (find-class '<C1>) :y 20))
35520
356
357(x-val (make-instance (find-class '<C1>) :x 10 :y 20))
35810
359
360(let ((m (defmethod initialize-instance ((inst <C1>) &rest ignore)
361           (call-next-method)
362           123)))
363  (eq m (find-method #'initialize-instance nil (list (find-class '<C1>)))))
364T
365
366(x-val (make-instance (find-class '<C1>) :x 101 :y 120))
367101
368
369(setf (find-class '<C1>) nil)
370nil
371
372(unintern '<C1>)
373T
374
375(eq (class-of ())               (find-class 'null))
376T
377
378(eq (class-of t)                (find-class 'symbol))
379T
380
381(eq (class-of 10)               (find-class #+(or ALLEGRO CMU SBCL OpenMCL LISPWORKS) 'fixnum #-(or ALLEGRO CMU SBCL OpenMCL LISPWORKS) 'integer))
382T
383
384(eq (class-of 10.0)             (find-class #+(or ALLEGRO CMU SBCL OpenMCL) 'single-float #-(or ALLEGRO CMU SBCL OpenMCL) 'float))
385T
386
387(eq (class-of '(a b))           (find-class 'cons))
388T
389
390(eq (class-of "abc")            (find-class #+CMU 'simple-string #+(or SBCL OpenMCL LISPWORKS) 'simple-base-string #-(or CMU SBCL OpenMCL LISPWORKS) 'string))
391T
392
393(eq (class-of '#(1 2))          (find-class #+(or CMU SBCL OpenMCL LISPWORKS) 'simple-vector #-(or CMU SBCL OpenMCL LISPWORKS) 'vector))
394T
395
396(eq (class-of #'car)            (find-class 'function))
397T
398
399(eq (class-of #'make-instance)  (find-class 'standard-generic-function))
400T
401
402(eq (class-of '#2a((a) (b)))    (find-class #+(or CMU SBCL LISPWORKS) 'simple-array #-(or CMU SBCL LISPWORKS) 'array))
403T
404
405(eq (class-of *standard-input*) (find-class 'stream))
406NIL
407
408(eq (class-of (lambda (x) x))   (find-class 'function))
409T
410
411(eq (class-of (find-class 't)) (find-class 'built-in-class))
412T
413
414(eq (class-of (make-array nil)) (find-class #+(or CMU SBCL LISPWORKS) 'simple-array #-(or CMU SBCL LISPWORKS) 'array))  T
415(eq (class-of (make-array nil :element-type nil)) (find-class #+(or CMU SBCL) 'simple-array #-(or CMU SBCL) 'array)) T
416(eq (class-of (make-array 10 :element-type nil)) (find-class #+CMU 'simple-string #+SBCL 'sb-kernel::simple-array-nil #-(or CMU SBCL) 'string)) T
417
418(typep "abc" (find-class 't))
419T
420
421(typep "abc" (find-class 'array))
422T
423
424(typep "abc" (find-class 'vector))
425T
426
427(typep "abc" (find-class 'string))
428T
429
430(typep "abc" (find-class 'integer))
431NIL
432
433(typep 3 (find-class 't))
434T
435
436(typep 3 (find-class 'number))
437T
438
439(typep 3 (find-class 'float))
440NIL
441
442(typep 3 (find-class 'integer))
443T
444
445(typep 3 (find-class 'string))
446NIL
447
448(not (not (typep *standard-input* (find-class 'stream))))
449T
450
451#+CLISP
452(defun subclassp (class1 class2)
453  (clos::subclassp class1 class2)
454)
455#+ALLEGRO
456(defun subclassp (class1 class2)
457  (finalize-inheritance class1)
458  (not (null (member class2 (class-precedence-list class1))))
459)
460#+CMU
461(defun subclassp (class1 class2)
462  (not (null (member (car (pcl:class-precedence-list class2))
463                     (pcl:class-precedence-list class1)
464) )    )     )
465#+SBCL
466(defun subclassp (class1 class2)
467  (not (null (member (car (sb-pcl:class-precedence-list class2))
468                     (sb-pcl:class-precedence-list class1)
469) )    )     )
470#+(or OpenMCL LISPWORKS)
471(defun subclassp (class1 class2)
472  (not (null (member class2 (class-precedence-list class1))))
473)
474#+(or CLISP ALLEGRO CMU SBCL OpenMCL LISPWORKS) SUBCLASSP
475
476(subclassp (find-class 'number)           (find-class 't))
477T
478
479(subclassp (find-class 'integer)          (find-class 'number))
480T
481
482(subclassp (find-class 'float)            (find-class 'number))
483T
484
485;; make-load-form
486(defun mlf-tester (symbol &optional
487                   (lisp-file "clos-tst-make-load-form-demo.lisp"))
488  (unwind-protect
489       (let (compiled-file)
490         (with-open-file (stream lisp-file :direction :output #+(or CMU SBCL) :if-exists #+(or CMU SBCL) :supersede)
491           (format stream "(in-package ~s)~%(defparameter ~S '#.~S)~%"
492                   (package-name (symbol-package symbol))
493                   symbol symbol))
494         (setq compiled-file (compile-file lisp-file))
495         (setf (symbol-value symbol) nil)
496         (load compiled-file)
497         (symbol-value symbol))
498    (post-compile-file-cleanup lisp-file)))
499MLF-TESTER
500
501(defun mlf-kill (type)
502  (let ((m (find-method #'make-load-form nil (list (find-class type)) nil)))
503    (when m (remove-method #'make-load-form m)))
504  (setf (find-class type) nil))
505mlf-kill
506
507;; from kmp
508(progn
509  (defclass test-class1 () ((foo :initarg :foo :accessor foo :initform 0)))
510  (defclass test-class2 () ((foo :initarg :foo :accessor foo :initform 0)))
511  (defmethod make-load-form ((obj test-class1) &optional environment)
512    (declare (ignore environment))
513    `(make-instance 'test-class1 :foo ',(foo obj)))
514  (defmethod make-load-form ((obj test-class2) &optional environment)
515    (declare (ignore environment))
516    `(make-instance 'test-class2 :foo ',(foo obj)))
517  (defparameter *t-list*
518    (list (make-instance 'test-class1 :foo 100)
519          (make-instance 'test-class2 :foo 200)))
520  (mlf-tester '*t-list*)
521  (mapcar #'foo *t-list*))
522(100 200)
523
524;; from Christophe Rhodes <csr21@cam.ac.uk>
525(defstruct foo a)
526FOO
527
528#-OpenMCL ; Bug in OpenMCL
529(progn
530  (defmethod make-load-form ((x foo) &optional env)
531    (make-load-form-saving-slots x :environment env))
532  (defparameter *tmp-file* "clos-tst-mlf-tmp.lisp")
533  (with-open-file (s *tmp-file* :direction :output #+(or CMU SBCL) :if-exists #+(or CMU SBCL) :supersede)
534    (format s "(defparameter *foo* '#S(FOO :A BAR-CONST))~%"))
535  (load (compile-file *tmp-file*))
536  *foo*)
537#-OpenMCL
538#S(FOO :A BAR-CONST)
539
540(progn
541  (makunbound '*foo*)
542  (defconstant bar-const 1)
543  (unwind-protect (progn (load (compile-file *tmp-file*)) *foo*)
544    (post-compile-file-cleanup *tmp-file*)
545    (mlf-kill 'foo)))
546#S(FOO :A BAR-CONST)
547
548#+SBCL (unintern 'foo) #+SBCL t
549#+SBCL (unintern 'copy-foo) #+SBCL t
550#+SBCL (unintern 'make-foo) #+SBCL t
551
552;; <http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Issues/iss215-writeup.html>
553(progn
554  (defclass pos ()
555    ((x :initarg :x :reader pos-x)
556     (y :initarg :y :reader pos-y)
557     (r :accessor pos-r)))
558  (defmethod shared-initialize :after ((self pos) ignore1 &rest ignore2)
559    (declare (ignore ignore1 ignore2))
560    (unless (slot-boundp self 'r)
561      (setf (pos-r self) (sqrt (+ (* (pos-x self) (pos-x self))
562                                  (* (pos-y self) (pos-y self)))))))
563  (defmethod make-load-form ((self pos) &optional environment)
564    (declare (ignore environment))
565    `(make-instance ',(class-name (class-of self))
566                    :x ',(pos-x self) :y ',(pos-y self)))
567  (setq *foo* (make-instance 'pos :x 3.0 :y 4.0))
568  (mlf-tester '*foo*)
569  (list (pos-x *foo*) (pos-y *foo*) (pos-r *foo*)))
570(3.0 4.0 5.0)
571
572(progn
573  (defclass tree-with-parent ()
574    ((parent :accessor tree-parent)
575     (children :initarg :children)))
576  (defmethod make-load-form ((x tree-with-parent) &optional environment)
577    (declare (ignore environment))
578    (values
579     ;; creation form
580     `(make-instance ',(class-name (class-of x)))
581     ;; initialization form
582     `(setf (tree-parent ',x) ',(slot-value x 'parent)
583            (slot-value ',x 'children) ',(slot-value x 'children))))
584  (setq *foo* (make-instance 'tree-with-parent :children
585                             (list (make-instance 'tree-with-parent
586                                                  :children nil)
587                                   (make-instance 'tree-with-parent
588                                                  :children nil))))
589  (setf (tree-parent *foo*) *foo*)
590  (dolist (ch (slot-value *foo* 'children))
591    (setf (tree-parent ch) *foo*))
592  (mlf-tester '*foo*)
593  (list (eq *foo* (tree-parent *foo*))
594        (every (lambda (x) (eq x *foo*))
595               (mapcar #'tree-parent (slot-value *foo* 'children)))
596        (every #'null
597               (mapcar (lambda (x) (slot-value x 'children))
598                       (slot-value *foo* 'children)))))
599(T T T)
600
601;; <http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Issues/iss237-writeup.html>
602(progn
603  (defparameter *initform-executed-counter* 0)
604  (defstruct foo (slot-1 (incf *initform-executed-counter*)))
605  (defparameter *foo* (make-foo)))
606*FOO*
607*foo*                           #S(FOO :SLOT-1 1)
608*initform-executed-counter*     1
609(progn
610  (mapc #'eval (multiple-value-list (make-load-form-saving-slots *foo*)))
611  *initform-executed-counter*)
6121
613(progn
614  (defmethod print-object ((f foo) (o stream))
615    (format o "~1t<~a>" (foo-slot-1 f)))
616  (prin1-to-string (make-foo)))
617" <2>"
618
619(progn (mlf-kill 'foo) nil)
620nil
621
622#+SBCL (unintern 'foo) #+SBCL t
623#+SBCL (unintern 'copy-foo) #+SBCL t
624#+SBCL (unintern 'make-foo) #+SBCL t
625
626(defstruct foo slot)
627FOO
628
629;; From: Kaz Kylheku <kaz@ashi.footprints.net>
630;; Date: Sat, 3 Jan 2004 14:47:25 -0800 (PST)
631;; http://article.gmane.org/gmane.lisp.clisp.general:7853
632;; https://sourceforge.net/p/clisp/mailman/message/11011470/
633(let ((file "clos-tst.lisp") c)
634  (unwind-protect
635       (progn
636         (makunbound '*foo*)
637         (with-open-file (f file :direction :output #+(or CMU SBCL) :if-exists #+(or CMU SBCL) :supersede)
638           (format f "(eval-when (compile load eval) (defstruct foo slot))~@
639                      (defparameter *foo* #.(make-foo))~%"))
640         (load (setq c (compile-file file)))
641         *foo*)
642    (post-compile-file-cleanup file)))
643#+(or CLISP GCL LISPWORKS) #S(FOO :SLOT NIL)
644#+(or ALLEGRO CMU SBCL) ERROR
645#-(or CLISP GCL ALLEGRO CMU SBCL LISPWORKS) UNKNOWN
646
647;; The finalized-direct-subclasses list must be weak.
648#+clisp
649(flet ((weak-list-length (w)
650         (if w (sys::%record-ref (sys::%record-ref w 0) 1) 0)))
651  (let (old1-weakpointers-count old-subclasses-count old2-weakpointers-count
652        new-subclasses-count new-weakpointers-count)
653    (defclass foo64a () ())
654    (defclass foo64b (foo64a) ())
655    (let ((usymbol (gensym)))
656      (eval `(defclass ,usymbol (foo64a) ()))
657      (setq old1-weakpointers-count (weak-list-length (clos::class-finalized-direct-subclasses-table (find-class 'foo64a))))
658      (setf (symbol-value usymbol) (1- (length (clos::list-all-finalized-subclasses (find-class 'foo64a)))))
659      (setq old2-weakpointers-count (weak-list-length (clos::class-finalized-direct-subclasses-table (find-class 'foo64a))))
660      (setq old-subclasses-count (symbol-value usymbol)))
661    (gc)
662    (setq new-subclasses-count (1- (length (clos::list-all-finalized-subclasses (find-class 'foo64a)))))
663    (setq new-weakpointers-count (weak-list-length (clos::class-finalized-direct-subclasses-table (find-class 'foo64a))))
664    (list old1-weakpointers-count old-subclasses-count old2-weakpointers-count
665          new-subclasses-count new-weakpointers-count)))
666#+clisp
667(2 2 2 1 1)
668
669;; The direct-subclasses list must be weak.
670#+clisp
671(let (old-weakpointers-count new-weakpointers-count)
672  (defclass foo64c () ())
673  (defclass foo64d (foo64c) ())
674  (let ((usymbol (gensym)))
675    (eval `(defclass ,usymbol (foo64c) ()))
676    (setq old-weakpointers-count (length (class-direct-subclasses (find-class 'foo64c))))
677    (setf (symbol-value usymbol) nil))
678  (gc)
679  (setq new-weakpointers-count (length (class-direct-subclasses (find-class 'foo64c))))
680  (list old-weakpointers-count new-weakpointers-count))
681#+clisp
682(2 1)
683
684;; change-class
685;; <http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/stagenfun_change-class.html>
686(progn
687  (defclass abstract-position () ())
688  (defclass x-y-position (abstract-position)
689    ((name :initarg :name)
690     (x :initform 0 :initarg :x)
691     (y :initform 0 :initarg :y)))
692  (defclass rho-theta-position (abstract-position)
693    ((name :initarg :name)
694     (rho :initform 0)
695     (theta :initform 0)))
696  (defmethod update-instance-for-different-class :before
697      ((old x-y-position) (new rho-theta-position) &key)
698    ;; Copy the position information from old to new to make new
699    ;; be a rho-theta-position at the same position as old.
700    (let ((x (slot-value old 'x))
701          (y (slot-value old 'y)))
702      (setf (slot-value new 'rho) (sqrt (+ (* x x) (* y y)))
703            (slot-value new 'theta) (atan y x))))
704  (setq p1 (make-instance 'x-y-position :name 'foo :x 2 :y 0)
705        p2 (make-instance 'x-y-position :name 'bar :x 1 :y 1))
706  (change-class p1 'rho-theta-position)
707  (change-class p2 'rho-theta-position)
708  (list (slot-value p1 'name) (slot-value p1 'rho) (slot-value p1 'theta)
709        (slot-value p2 'name) (slot-value p2 'rho) (slot-value p2 'theta)))
710#+CLISP (FOO 2 0 BAR 1.4142135 0.7853981)
711#+(or ALLEGRO CMU SBCL OpenMCL) (FOO 2.0 0.0 BAR 1.4142135 0.7853982)
712#+GCL (FOO 2.0 0.0 BAR 1.4142135623730951 0.78539816339744828)
713#+LISPWORKS (FOO 2.0 0.0 BAR 1.4142135623730951 0.7853981633974483)
714#-(or CLISP GCL ALLEGRO CMU SBCL OpenMCL LISPWORKS) UNKNOWN
715
716(progn
717  (defclass c0 () (a b c))
718  (defclass c1 () (b c a))
719  (setq i (make-instance 'c0))
720  (setf (slot-value i 'a) 1 (slot-value i 'b) 2 (slot-value i 'c) 3)
721  (change-class i 'c1)
722  (list (slot-value i 'a) (slot-value i 'b) (slot-value i 'c)))
723(1 2 3)
724
725;; https://sourceforge.net/p/clisp/bugs/195/
726(progn
727  (defclass c1 () ())
728  (defclass c2 () ())
729  (list
730   (let ((c (make-instance 'c1)))
731     (list (type-of (change-class c 'c2))
732           (type-of (change-class c 'c1))))
733   (let ((c (make-instance 'c1)))
734     (list (type-of (change-class c 'c1))
735           (type-of (change-class c 'c1))))))
736((C2 C1) (C1 C1))
737
738;; Check that change-class uses its initargs.
739(progn
740  (defclass c7 () ((name :initarg :name)))
741  (defclass c8 () ((people :initarg :people) name))
742  (let ((x (make-instance 'c7 :name 'queen-mary)))
743    (change-class x 'c8 :people 700)
744    (list (slot-value x 'name) (slot-value x 'people))))
745(QUEEN-MARY 700)
746
747;; Check that a GC collects the forward pointer left over by change-class.
748#+CLISP
749(progn
750  (defclass c3 () (a b c))
751  (defclass c4 () (b c d e))
752  (let* ((i (make-instance 'c3))
753         (nslots-before (sys::%record-length i)))
754    (change-class i 'c4)
755    (gc)
756    (< nslots-before (sys::%record-length i))))
757#+CLISP
758T
759
760;; Redefining a finalized class must not change its identity.
761(let (c1 c2)
762  (defclass foo60-b () ())
763  (defclass foo60-a (foo60-b) ())
764  (make-instance 'foo60-b)
765  (setq c1 (find-class 'foo60-a))
766  (defclass foo60-a () ())
767  (setq c2 (find-class 'foo60-a))
768  (eq c1 c2))
769T
770
771;; Redefining a non-finalized class must not change its identity.
772(let (c1 c2)
773  (defclass foo61-a (foo61-b) ())
774  (setq c1 (find-class 'foo61-a))
775  (defclass foo61-a () ())
776  (setq c2 (find-class 'foo61-a))
777  (eq c1 c2))
778T
779
780;; SUBTYPEP must work on finalized classes.
781(progn
782  (defclass foo62-b (foo62-a) ())
783  (defclass foo62-c (foo62-b) ())
784  (defclass foo62-a () ())
785  (make-instance 'foo62-c)
786  (list (subtypep 'foo62-b 'foo62-b)
787        (subtypep 'foo62-c 'foo62-b)
788        (subtypep 'foo62-b 'foo62-c)))
789(T T NIL)
790
791;; SUBTYPEP must work on non-finalized classes.
792(progn
793  (defclass foo63-b (foo63-a) ())
794  (defclass foo63-c (foo63-b) ())
795  (defclass foo63-a () ())
796  (list (subtypep 'foo63-b 'foo63-b)
797        (subtypep 'foo63-c 'foo63-b)
798        (subtypep 'foo63-b 'foo63-c)))
799(T T NIL)
800
801;; Redefining a class can make it (and also its subclasses) non-finalized.
802#+CLISP
803(let (fa fb fc)
804  (defclass foo65a () ())
805  (defclass foo65b (foo65a) ())
806  (defclass foo65c (foo65b) ())
807  (setq fa (clos:class-finalized-p (find-class 'foo65a))
808        fb (clos:class-finalized-p (find-class 'foo65b))
809        fc (clos:class-finalized-p (find-class 'foo65c)))
810  (defclass foo65b (foo65a foo65other) ())
811  (list fa fb fc
812        (clos:class-finalized-p (find-class 'foo65a))
813        (clos:class-finalized-p (find-class 'foo65b))
814        (clos:class-finalized-p (find-class 'foo65c))))
815#+CLISP
816(T T T T NIL NIL)
817
818;; update-instance-for-redefined-class
819;; <http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/stagenfun_upd_efined-class.html>
820(progn
821  (defclass abstract-position () ())
822  (defclass x-y-position (abstract-position)
823    ((x :initform 0 :accessor position-x)
824     (y :initform 0 :accessor position-y)))
825  (setf i (make-instance 'x-y-position)
826        (position-x i) 1d0
827        (position-y i) 1d0)
828  (type-of i))
829x-y-position
830
831(progn
832  ;; It turns out polar coordinates are used more than Cartesian
833  ;; coordinates, so the representation is altered and some new
834  ;; accessor methods are added.
835  (defmethod update-instance-for-redefined-class :before
836      ((pos x-y-position) added deleted plist &key)
837    ;; Transform the x-y coordinates to polar coordinates
838    ;; and store into the new slots.
839    (let ((x (getf plist 'x))
840          (y (getf plist 'y)))
841      (setf (position-rho pos) (sqrt (+ (* x x) (* y y)))
842            (position-theta pos) (atan y x))))
843  (defclass x-y-position (abstract-position)
844    ((rho :initform 0 :accessor position-rho)
845     (theta :initform 0 :accessor position-theta)))
846  ;; All instances of the old x-y-position class will be updated
847  ;; automatically.
848  ;; The new representation is given the look and feel of the old one.
849  (defmethod position-x ((pos x-y-position))
850    (with-slots (rho theta) pos (* rho (cos theta))))
851  (defmethod (setf position-x) (new-x (pos x-y-position))
852    (with-slots (rho theta) pos
853      (let ((y (position-y pos)))
854        (setq rho (sqrt (+ (* new-x new-x) (* y y)))
855              theta (atan y new-x))
856        new-x)))
857  (defmethod position-y ((pos x-y-position))
858    (with-slots (rho theta) pos (* rho (sin theta))))
859  (defmethod (setf position-y) (new-y (pos x-y-position))
860    (with-slots (rho theta) pos
861      (let ((x (position-x pos)))
862        (setq rho (sqrt (+ (* x x) (* new-y new-y)))
863              theta (atan new-y x))
864        new-y)))
865  (list (type-of i) (position-x i) (position-y i)
866        (position-rho i) (position-theta i)))
867#+OpenMCL (X-Y-POSITION 1.0d0 1.0000000000000002d0
868                        1.4142135623730951d0 0.7853981633974483d0)
869#-OpenMCL (X-Y-POSITION 1.0000000000000002d0 1.0d0
870                        1.4142135623730951d0 0.7853981633974483d0)
871
872
873;; 4.3.6. Redefining Classes
874
875;; Newly added local slot.
876;; 4.3.6.1.: "Local slots specified by the new class definition that are not
877;;            specified as either local or shared by the old class are added."
878(multiple-value-bind (value condition)
879    (ignore-errors
880      (defclass foo70 () ())
881      (setq i (make-instance 'foo70))
882      (defclass foo70 () ((size :initarg :size :initform 1) (other)))
883      (slot-value i 'size))
884  (list value (typep condition 'error)))
885(1 NIL)
886
887;; Newly added shared slot.
888;; 4.3.6.: "Newly added shared slots are initialized."
889(multiple-value-bind (value condition)
890    (ignore-errors
891      (defclass foo71 () ())
892      (setq i (make-instance 'foo71))
893      (defclass foo71 () ((size :initarg :size :initform 1 :allocation :class) (other)))
894      (slot-value i 'size))
895  (list value (typep condition 'error)))
896(1 NIL)
897
898;; Discarded local slot.
899;; 4.3.6.1.: "Slots not specified as either local or shared by the new class
900;;            definition that are specified as local by the old class are
901;;            discarded."
902(multiple-value-bind (value condition)
903    (ignore-errors
904      (defclass foo72 () ((size :initarg :size :initform 1)))
905      (setq i (make-instance 'foo72 :size 5))
906      (defclass foo72 () ((other)))
907      (slot-value i 'size))
908  (list value (typep condition 'error)))
909(NIL T)
910
911;; Discarded shared slot.
912(multiple-value-bind (value condition)
913    (ignore-errors
914      (defclass foo73 () ((size :initarg :size :initform 1 :allocation :class)))
915      (setq i (make-instance 'foo73))
916      (defclass foo73 () ((other)))
917      (slot-value i 'size))
918  (list value (typep condition 'error)))
919(NIL T)
920
921;; Shared slot remains shared.
922;; 4.3.6.: "The value of a slot that is specified as shared both in the old
923;;          class and in the new class is retained."
924(multiple-value-bind (value condition)
925    (ignore-errors
926      (defclass foo74 () ((size :initarg :size :initform 1 :allocation :class)))
927      (setq i (make-instance 'foo74))
928      (defclass foo74 () ((size :initarg :size :initform 2 :allocation :class) (other)))
929      (slot-value i 'size))
930  (list value (typep condition 'error)))
931(1 NIL)
932
933;; Shared slot becomes local.
934;; 4.3.6.1.: "The value of a slot that is specified as shared in the old class
935;;            and as local in the new class is retained."
936(multiple-value-bind (value condition)
937    (ignore-errors
938      (defclass foo75 () ((size :initarg :size :initform 1 :allocation :class)))
939      (setq i (make-instance 'foo75))
940      (defclass foo75 () ((size :initarg :size :initform 2) (other)))
941      (slot-value i 'size))
942  (list value (typep condition 'error)))
943(1 NIL)
944
945;; Local slot remains local.
946;; 4.3.6.1.: "The values of local slots specified by both the new and old
947;;            classes are retained."
948(multiple-value-bind (value condition)
949    (ignore-errors
950      (defclass foo76 () ((size :initarg :size :initform 1)))
951      (setq i (make-instance 'foo76 :size 5))
952      (defclass foo76 () ((size :initarg :size :initform 2) (other)))
953      (slot-value i 'size))
954  (list value (typep condition 'error)))
955(5 NIL)
956
957;; Local slot becomes shared.
958;; 4.3.6.: "Slots that were local in the old class and that are shared in the
959;;          new class are initialized."
960(multiple-value-bind (value condition)
961    (ignore-errors
962      (defclass foo77 () ((size :initarg :size :initform 1)))
963      (setq i (make-instance 'foo77 :size 5))
964      (defclass foo77 () ((size :initarg :size :initform 2 :allocation :class) (other)))
965      (slot-value i 'size))
966  (list value (typep condition 'error)))
967(2 NIL)
968
969
970;; Redefining the superclass of an instance
971
972;; Newly added local slot.
973;; 4.3.6.1.: "Local slots specified by the new class definition that are not
974;;            specified as either local or shared by the old class are added."
975(multiple-value-bind (value condition)
976    (ignore-errors
977      (defclass foo80a () ())
978      (defclass foo80b (foo80a) ())
979      (setq i (make-instance 'foo80b))
980      (defclass foo80a () ((size :initarg :size :initform 1) (other)))
981      (slot-value i 'size))
982  (list value (typep condition 'error)))
983(1 NIL)
984
985;; Newly added shared slot.
986;; 4.3.6.: "Newly added shared slots are initialized."
987(multiple-value-bind (value condition)
988    (ignore-errors
989      (defclass foo81a () ())
990      (defclass foo81b (foo81a) ())
991      (setq i (make-instance 'foo81b))
992      (defclass foo81a () ((size :initarg :size :initform 1 :allocation :class) (other)))
993      (slot-value i 'size))
994  (list value (typep condition 'error)))
995(1 NIL)
996
997;; Discarded local slot.
998;; 4.3.6.1.: "Slots not specified as either local or shared by the new class
999;;            definition that are specified as local by the old class are
1000;;            discarded."
1001(multiple-value-bind (value condition)
1002    (ignore-errors
1003      (defclass foo82a () ((size :initarg :size :initform 1)))
1004      (defclass foo82b (foo82a) ())
1005      (setq i (make-instance 'foo82b :size 5))
1006      (defclass foo82a () ((other)))
1007      (slot-value i 'size))
1008  (list value (typep condition 'error)))
1009(NIL T)
1010
1011;; Discarded shared slot.
1012(multiple-value-bind (value condition)
1013    (ignore-errors
1014      (defclass foo83a () ((size :initarg :size :initform 1 :allocation :class)))
1015      (defclass foo83b (foo83a) ())
1016      (setq i (make-instance 'foo83b))
1017      (defclass foo83a () ((other)))
1018      (slot-value i 'size))
1019  (list value (typep condition 'error)))
1020(NIL T)
1021
1022;; Shared slot remains shared.
1023;; 4.3.6.: "The value of a slot that is specified as shared both in the old
1024;;          class and in the new class is retained."
1025(multiple-value-bind (value condition)
1026    (ignore-errors
1027      (defclass foo84a () ((size :initarg :size :initform 1 :allocation :class)))
1028      (defclass foo84b (foo84a) ())
1029      (setq i (make-instance 'foo84b))
1030      (defclass foo84a () ((size :initarg :size :initform 2 :allocation :class) (other)))
1031      (slot-value i 'size))
1032  (list value (typep condition 'error)))
1033(1 NIL)
1034
1035;; Shared slot becomes local.
1036;; 4.3.6.1.: "The value of a slot that is specified as shared in the old class
1037;;            and as local in the new class is retained."
1038(multiple-value-bind (value condition)
1039    (ignore-errors
1040      (defclass foo85a () ((size :initarg :size :initform 1 :allocation :class)))
1041      (defclass foo85b (foo85a) ())
1042      (setq i (make-instance 'foo85b))
1043      (defclass foo85a () ((size :initarg :size :initform 2) (other)))
1044      (slot-value i 'size))
1045  (list value (typep condition 'error)))
1046(1 NIL)
1047
1048;; Local slot remains local.
1049;; 4.3.6.1.: "The values of local slots specified by both the new and old
1050;;            classes are retained."
1051(multiple-value-bind (value condition)
1052    (ignore-errors
1053      (defclass foo86a () ((size :initarg :size :initform 1)))
1054      (defclass foo86b (foo86a) ())
1055      (setq i (make-instance 'foo86b :size 5))
1056      (defclass foo86a () ((size :initarg :size :initform 2) (other)))
1057      (slot-value i 'size))
1058  (list value (typep condition 'error)))
1059(5 NIL)
1060
1061;; Local slot becomes shared.
1062;; 4.3.6.: "Slots that were local in the old class and that are shared in the
1063;;          new class are initialized."
1064(multiple-value-bind (value condition)
1065    (ignore-errors
1066      (defclass foo87a () ((size :initarg :size :initform 1)))
1067      (defclass foo87b (foo87a) ())
1068      (setq i (make-instance 'foo87b :size 5))
1069      (defclass foo87a () ((size :initarg :size :initform 2 :allocation :class) (other)))
1070      (slot-value i 'size))
1071  (list value (typep condition 'error)))
1072(2 NIL)
1073
1074
1075;; The clos::list-finalized-direct-subclasses function lists only finalized
1076;; direct subclasses.
1077#+CLISP
1078(progn
1079  (defclass foo88b (foo88a) ((s :initarg :s)))
1080  (defclass foo88c (b) ())
1081  (defclass foo88a () ())
1082  ; Here foo88a is finalized, foo88b and foo88c are not.
1083  (list
1084    (length (clos::list-finalized-direct-subclasses (find-class 'foo88a)))
1085    (length (clos::list-finalized-direct-subclasses (find-class 'foo88b)))
1086    (length (clos::list-finalized-direct-subclasses (find-class 'foo88c)))))
1087#+CLISP
1088(0 0 0)
1089#+CLISP
1090(progn
1091  (defclass foo89b (foo89a) ((s :initarg :s)))
1092  (defclass foo89c (b) ())
1093  (defclass foo89a () ())
1094  (let ((x (make-instance 'foo89b :s 5)))
1095    ; Here foo89a and foo89b are finalized, foo89c is not.
1096    (list
1097      (length (clos::list-finalized-direct-subclasses (find-class 'foo89a)))
1098      (length (clos::list-finalized-direct-subclasses (find-class 'foo89b)))
1099      (length (clos::list-finalized-direct-subclasses (find-class 'foo89c))))))
1100#+CLISP
1101(1 0 0)
1102
1103;; The clos::list-finalized-direct-subclasses function must notice when a
1104;; finalized direct subclass is redefined in such a way that it is no longer
1105;; a subclass.
1106#+CLISP
1107(progn
1108  (defclass foo90b (foo90a) ((s :initarg :s)))
1109  (defclass foo90c (foo90b) ())
1110  (defclass foo90a () ())
1111  (let ((x (make-instance 'foo90b :s 5)))
1112    ; Here foo90a and foo90b are finalized, foo90c is not.
1113    (defclass foo90b () (s))
1114    ; Now foo90b is no longer direct subclass of foo90a.
1115    (list
1116      (length (clos::list-finalized-direct-subclasses (find-class 'foo90a)))
1117      (length (clos::list-finalized-direct-subclasses (find-class 'foo90b)))
1118      (length (clos::list-finalized-direct-subclasses (find-class 'foo90c))))))
1119#+CLISP
1120(0 0 0)
1121
1122;; The clos::list-finalized-direct-subclasses function must notice when a
1123;; finalized direct subclass is redefined in such a way that it is no longer
1124;; finalized.
1125#+CLISP
1126(progn
1127  (defclass foo91a () ())
1128  (defclass foo91b (foo91a) ())
1129  (defclass foo91c (foo91b) ())
1130  (defclass foo91b (foo91a foo91other) ())
1131  (list
1132    (length (clos::list-finalized-direct-subclasses (find-class 'foo91a)))
1133    (length (clos::list-finalized-direct-subclasses (find-class 'foo91b)))
1134    (length (clos::list-finalized-direct-subclasses (find-class 'foo91c)))))
1135#+CLISP
1136(0 0 0)
1137
1138;; make-instances-obsolete causes update-instance-for-redefined-class to
1139;; be called on instances of current subclasses.
1140(progn
1141  (defclass foo92b (foo92a) ((s :initarg :s)))
1142  (defclass foo92a () ())
1143  (let ((x (make-instance 'foo92b :s 5)) (update-counter 0))
1144    (defclass foo92b (foo92a) ((s) (s1) (s2))) ; still subclass of foo92a
1145    (slot-value x 's)
1146    (defmethod update-instance-for-redefined-class ((object foo92b) added-slots discarded-slots property-list &rest initargs)
1147      (incf update-counter))
1148    (make-instances-obsolete 'foo92a)
1149    (slot-value x 's)
1150    update-counter))
11511
1152
1153;; make-instances-obsolete does not cause update-instance-for-redefined-class
1154;; to be called on instances of ancient subclasses.
1155(progn
1156  (defclass foo93b (foo93a) ((s :initarg :s)))
1157  (defclass foo93a () ())
1158  (let ((x (make-instance 'foo93b :s 5)) (update-counter 0))
1159    (defclass foo93b () ((s) (s1) (s2))) ; no longer a subclass of foo93a
1160    (slot-value x 's)
1161    (defmethod update-instance-for-redefined-class ((object foo93b) added-slots discarded-slots property-list &rest initargs)
1162      (incf update-counter))
1163    (make-instances-obsolete 'foo93a)
1164    (slot-value x 's)
1165    update-counter))
11660
1167
1168;; Redefining a class removes the slot accessors installed on behalf of the
1169;; old class.
1170(progn
1171  (defclass foo94 () ((a :reader foo94-get-a :writer foo94-set-a)
1172                      (b :reader foo94-get-b :writer foo94-set-b)
1173                      (c :accessor foo94-c)
1174                      (d :accessor foo94-d)
1175                      (e :accessor foo94-e)))
1176  (list* (not (null (find-method #'foo94-get-a '() (list (find-class 'foo94)) nil)))
1177         (not (null (find-method #'foo94-set-a '() (list (find-class 't) (find-class 'foo94)) nil)))
1178         (not (null (find-method #'foo94-get-b '() (list (find-class 'foo94)) nil)))
1179         (not (null (find-method #'foo94-set-b '() (list (find-class 't) (find-class 'foo94)) nil)))
1180         (not (null (find-method #'foo94-c '() (list (find-class 'foo94)) nil)))
1181         (not (null (find-method #'(setf foo94-c) '() (list (find-class 't) (find-class 'foo94)) nil)))
1182         (not (null (find-method #'foo94-d '() (list (find-class 'foo94)) nil)))
1183         (not (null (find-method #'(setf foo94-d) '() (list (find-class 't) (find-class 'foo94)) nil)))
1184         (not (null (find-method #'foo94-e '() (list (find-class 'foo94)) nil)))
1185         (not (null (find-method #'(setf foo94-e) '() (list (find-class 't) (find-class 'foo94)) nil)))
1186         (progn
1187           (defclass foo94 () ((a :reader foo94-get-a :writer foo94-set-a)
1188                               (b)
1189                               (c :accessor foo94-c)
1190                               (e :accessor foo94-other-e)))
1191           (list (not (null (find-method #'foo94-get-a '() (list (find-class 'foo94)) nil)))
1192                 (not (null (find-method #'foo94-set-a '() (list (find-class 't) (find-class 'foo94)) nil)))
1193                 (not (null (find-method #'foo94-get-b '() (list (find-class 'foo94)) nil)))
1194                 (not (null (find-method #'foo94-set-b '() (list (find-class 't) (find-class 'foo94)) nil)))
1195                 (not (null (find-method #'foo94-c '() (list (find-class 'foo94)) nil)))
1196                 (not (null (find-method #'(setf foo94-c) '() (list (find-class 't) (find-class 'foo94)) nil)))
1197                 (not (null (find-method #'foo94-d '() (list (find-class 'foo94)) nil)))
1198                 (not (null (find-method #'(setf foo94-d) '() (list (find-class 't) (find-class 'foo94)) nil)))
1199                 (not (null (find-method #'foo94-e '() (list (find-class 'foo94)) nil)))
1200                 (not (null (find-method #'(setf foo94-e) '() (list (find-class 't) (find-class 'foo94)) nil)))))))
1201(T T T T T T T T T T
1202 T T NIL NIL T T NIL NIL NIL NIL)
1203
1204;; It is possible to redefine a class in a way that makes it non-finalized,
1205;; if it was not yet instantiated.
1206(progn
1207  (defclass foo95b () ((s :initarg :s :accessor foo95b-s)))
1208  (defclass foo95b (foo95a) ((s :accessor foo95b-s)))
1209  t)
1210T
1211
1212;; When redefining a class in a way that makes it non-finalized, and it was
1213;; already instantiated, an error is signalled, and the instances survive it.
1214(let ((notes '()))
1215  (flet ((note (o) (setq notes (append notes (list o)))))
1216    (defclass foo96b () ((s :initarg :s :accessor foo96b-s)))
1217    (let ((x (make-instance 'foo96b :s 5)))
1218      (note (foo96b-s x))
1219      (note
1220        (typep
1221          (second
1222            (multiple-value-list
1223              (ignore-errors
1224                (defclass foo96b (foo96a) ((s :accessor foo96b-s))))))
1225          'error))
1226      (note (foo96b-s x))
1227      (note (slot-value x 's))
1228      (defclass foo96a () ((r :accessor foo96b-r)))
1229      (note (foo96b-s x))
1230      (note (slot-value x 's))
1231      (note (subtypep 'foo96b 'foo96a))
1232      notes)))
1233(5 T 5 5 5 5 NIL)
1234(let ((notes '()))
1235  (flet ((note (o) (setq notes (append notes (list o)))))
1236    (defclass foo97b () ((s :initarg :s :accessor foo97b-s)))
1237    (let ((x (make-instance 'foo97b :s 5)))
1238      (note (foo97b-s x))
1239      (note
1240        (typep
1241          (second
1242            (multiple-value-list
1243              (ignore-errors
1244                (defclass foo97b (foo97a) ((s :accessor foo97b-s))))))
1245          'error))
1246      (note (foo97b-s x))
1247      (note (slot-value x 's))
1248      (defclass foo97a () ((r :accessor foo97b-r)))
1249      (note (foo97b-s x))
1250      (note (slot-value x 's))
1251      (note (subtypep 'foo97b 'foo97a))
1252      notes)))
1253(5 T 5 5 5 5 NIL)
1254
1255
1256;; Test the :fixed-slot-location option.
1257
1258; Single class.
1259#+CLISP
1260(progn
1261  (defclass foo100 () (a b c) (:fixed-slot-locations t))
1262  (mapcar #'(lambda (name)
1263              (let ((slot (find name (clos::class-slots (find-class 'foo100))
1264                                :key #'clos:slot-definition-name)))
1265                (clos:slot-definition-location slot)))
1266          '(a b c)))
1267#+CLISP
1268(1 2 3)
1269
1270; Simple subclass.
1271#+CLISP
1272(progn
1273  (defclass foo101a () (a b c) (:fixed-slot-locations t))
1274  (defclass foo101b (foo101a) (d e f) (:fixed-slot-locations t))
1275  (mapcar #'(lambda (name)
1276              (let ((slot (find name (clos::class-slots (find-class 'foo101b))
1277                                :key #'clos:slot-definition-name)))
1278                (clos:slot-definition-location slot)))
1279          '(a b c d e f)))
1280#+CLISP
1281(1 2 3 4 5 6)
1282
1283; Subclass with multiple inheritance.
1284#+CLISP
1285(progn
1286  (defclass foo102a () (a b c) (:fixed-slot-locations t))
1287  (defclass foo102b () (d e f))
1288  (defclass foo102c (foo102a foo102b) (g h i))
1289  (mapcar #'(lambda (name)
1290              (let ((slot (find name (clos::class-slots (find-class 'foo102c))
1291                                :key #'clos:slot-definition-name)))
1292                (clos:slot-definition-location slot)))
1293          '(a b c d e f g h i)))
1294#+CLISP
1295(1 2 3 4 5 6 7 8 9)
1296
1297; Subclass with multiple inheritance.
1298#+CLISP
1299(progn
1300  (defclass foo103a () (a b c))
1301  (defclass foo103b () (d e f) (:fixed-slot-locations t))
1302  (defclass foo103c (foo103a foo103b) (g h i))
1303  (mapcar #'(lambda (name)
1304              (let ((slot (find name (clos::class-slots (find-class 'foo103c))
1305                                :key #'clos:slot-definition-name)))
1306                (clos:slot-definition-location slot)))
1307          '(a b c d e f g h i)))
1308#+CLISP
1309(4 5 6 1 2 3 7 8 9)
1310
1311; Subclass with multiple inheritance and collision.
1312#+CLISP
1313(progn
1314  (defclass foo104a () (a b c) (:fixed-slot-locations t))
1315  (defclass foo104b () (d e f) (:fixed-slot-locations t))
1316  (defclass foo104c (foo104a foo104b) (g h i))
1317  t)
1318#+CLISP
1319ERROR
1320
1321; Subclass with multiple inheritance and no collision.
1322#+CLISP
1323(progn
1324  (defclass foo105a () (a b c) (:fixed-slot-locations t))
1325  (defclass foo105b () () (:fixed-slot-locations t))
1326  (defclass foo105c (foo105a foo105b) (g h i))
1327  (mapcar #'(lambda (name)
1328              (let ((slot (find name (clos::class-slots (find-class 'foo105c))
1329                                :key #'clos:slot-definition-name)))
1330                (clos:slot-definition-location slot)))
1331          '(a b c g h i)))
1332#+CLISP
1333(1 2 3 4 5 6)
1334
1335; Subclass with multiple inheritance and no collision.
1336#+CLISP
1337(progn
1338  (defclass foo106a () () (:fixed-slot-locations t))
1339  (defclass foo106b () (d e f) (:fixed-slot-locations t))
1340  (defclass foo106c (foo106a foo106b) (g h i))
1341  (mapcar #'(lambda (name)
1342              (let ((slot (find name (clos::class-slots (find-class 'foo106c))
1343                                :key #'clos:slot-definition-name)))
1344                (clos:slot-definition-location slot)))
1345          '(d e f g h i)))
1346#+CLISP
1347(1 2 3 4 5 6)
1348
1349; Subclass with shared slots.
1350#+CLISP
1351(progn
1352  (defclass foo107a ()
1353    ((a :allocation :instance)
1354     (b :allocation :instance)
1355     (c :allocation :class)
1356     (d :allocation :class)
1357     (e :allocation :class))
1358    (:fixed-slot-locations t))
1359  (defclass foo107b (foo107a)
1360    ((b :allocation :class)))
1361  t)
1362#+CLISP
1363ERROR
1364
1365; Subclass with shared slots and no collision.
1366#+CLISP
1367(progn
1368  (defclass foo108a ()
1369    ((a :allocation :instance)
1370     (b :allocation :instance)
1371     (c :allocation :class)
1372     (d :allocation :class)
1373     (e :allocation :class))
1374    (:fixed-slot-locations t))
1375  (defclass foo108b (foo108a)
1376    (; (b :allocation :class) ; gives error, see above
1377     (c :allocation :instance)
1378     (d :allocation :class)
1379     (f :allocation :instance)
1380     (g :allocation :class)))
1381  (mapcar #'(lambda (name)
1382              (let ((slot (find name (clos::class-slots (find-class 'foo108b))
1383                                :key #'clos:slot-definition-name)))
1384                (let ((location (clos:slot-definition-location slot)))
1385                  (if (consp location)
1386                    (class-name (clos::cv-newest-class (car location)))
1387                    location))))
1388          '(a b c d e f g)))
1389#+CLISP
1390(1 2 3 foo108b foo108a 4 foo108b)
1391
1392;; Check that two classes with the same name can have different documentation
1393;; strings.
1394(let ((class1 (defclass foo109 () () (:documentation "first"))))
1395  (cons (documentation class1 't)
1396        (progn
1397          (setf (find-class 'foo109) nil)
1398          (let ((class2 (defclass foo109 () () (:documentation "second"))))
1399            (list (documentation class1 't)
1400                  (documentation class2 't))))))
1401("first" "first" "second")
1402
1403;; Check that invalid class options are rejected.
1404(defclass foo116 () () (:name bar))
1405ERROR
1406(defclass foo117 () () (:direct-superclasses baz))
1407ERROR
1408(defclass foo118 () () (:direct-slots x))
1409ERROR
1410(defclass foo119 () () (:direct-default-initargs (:x 5)))
1411ERROR
1412(defclass foo120 () () (:other-option blabla))
1413ERROR
1414
1415;; Check that invalid slot options are rejected.
1416(defclass foo121 () ((x :name bar)))
1417ERROR
1418(defclass foo122 () ((x :readers (bar))))
1419ERROR
1420(defclass foo123 () ((x :writers (bar))))
1421ERROR
1422(defclass foo124 () ((x :initargs (bar))))
1423ERROR
1424(defclass foo125 () ((x :initform 17 :initfunction (lambda () 42))))
1425ERROR
1426
1427
1428;;; Check that changing an object's class clears the effective-methods or
1429;;; discriminating-function cache of all affected generic functions.
1430(progn
1431  (defclass testclass31a () ())
1432  (defclass testclass31b (testclass31a) ())
1433  (defclass testclass31c (testclass31b) ())
1434  (let ((*p* (make-instance 'testclass31c)))
1435    (defgeneric testgf37 (x))
1436    (defmethod testgf37 ((x testclass31a)) (list 'a))
1437    (defmethod testgf37 ((x testclass31b)) (cons 'b (call-next-method)))
1438    (defmethod testgf37 ((x testclass31c)) (cons 'c (call-next-method)))
1439    (defmethod testgf37 ((x (eql *p*))) (cons '*p* (call-next-method)))
1440    (list
1441      (testgf37 *p*)
1442      (progn
1443        (change-class *p* 'testclass31b)
1444        (testgf37 *p*)))))
1445((*P* C B A) (*P* B A))
1446
1447
1448;;; Check that redefining a class with different class-precedence-list
1449;;; clears the effective-methods or discriminating-function cache of all
1450;;; affected generic functions.
1451
1452;; Class specializers.
1453
1454; Case 1: Adding a class to a CPL.
1455(progn
1456  (defclass testclass40a () ())
1457  (defclass testclass40b () ())
1458  (defclass testclass40c (testclass40b) ())
1459  (defgeneric testgf40 (x) (:method-combination list))
1460  (defmethod testgf40 list ((x standard-object)) 0)
1461  (defmethod testgf40 list ((x testclass40a)) 'a)
1462  (let ((inst (make-instance 'testclass40c)))
1463    (list
1464      (testgf40 inst)
1465      (progn
1466        (defclass testclass40b (testclass40a) ())
1467        (testgf40 inst)))))
1468((0) (A 0))
1469
1470; Case 2: Removing a class from a CPL.
1471(progn
1472  (defclass testclass41a () ())
1473  (defclass testclass41b (testclass41a) ())
1474  (defclass testclass41c (testclass41b) ())
1475  (defgeneric testgf41 (x) (:method-combination list))
1476  (defmethod testgf41 list ((x standard-object)) 0)
1477  (defmethod testgf41 list ((x testclass41a)) 'a)
1478  (let ((inst (make-instance 'testclass41c)))
1479    (list
1480      (testgf41 inst)
1481      (progn
1482        (defclass testclass41b () ())
1483        (testgf41 inst)))))
1484((A 0) (0))
1485
1486; Case 3: Reordering a CPL.
1487(progn
1488  (defclass testclass42a () ())
1489  (defclass testclass42b () ())
1490  (defclass testclass42c (testclass42a testclass42b) ())
1491  (defgeneric testgf42 (x))
1492  (defmethod testgf42 ((x testclass42a)) 'a)
1493  (defmethod testgf42 ((x testclass42b)) 'b)
1494  (let ((inst (make-instance 'testclass42c)))
1495    (list
1496      (testgf42 inst)
1497      (progn
1498        (defclass testclass42c (testclass42b testclass42a) ())
1499        (testgf42 inst)))))
1500(A B)
1501
1502;; EQL specializers.
1503
1504; Case 1: Adding a class to a CPL.
1505(progn
1506  (defclass testclass45a () ())
1507  (defclass testclass45b () ())
1508  (defclass testclass45c (testclass45b) ())
1509  (let ((inst (make-instance 'testclass45c)))
1510    (defgeneric testgf45 (x) (:method-combination list))
1511    (defmethod testgf45 list ((x testclass45a)) 'a)
1512    (defmethod testgf45 list ((x (eql inst))) 'inst)
1513    (list
1514      (testgf45 inst)
1515      (progn
1516        (defclass testclass45b (testclass45a) ())
1517        (testgf45 inst)))))
1518((INST) (INST A))
1519
1520; Case 2: Removing a class from a CPL.
1521(progn
1522  (defclass testclass46a () ())
1523  (defclass testclass46b (testclass46a) ())
1524  (defclass testclass46c (testclass46b) ())
1525  (let ((inst (make-instance 'testclass46c)))
1526    (defgeneric testgf46 (x) (:method-combination list))
1527    (defmethod testgf46 list ((x testclass46a)) 'a)
1528    (defmethod testgf46 list ((x (eql inst))) 'inst)
1529    (list
1530      (testgf46 inst)
1531      (progn
1532        (defclass testclass46b () ())
1533        (testgf46 inst)))))
1534((INST A) (INST))
1535
1536; Case 3: Reordering a CPL.
1537(progn
1538  (defclass testclass47a () ())
1539  (defclass testclass47b () ())
1540  (defclass testclass47c (testclass47a testclass47b) ())
1541  (let ((inst (make-instance 'testclass47c)))
1542    (defgeneric testgf47 (x))
1543    (defmethod testgf47 ((x testclass47a)) 'a)
1544    (defmethod testgf47 ((x testclass47b)) 'b)
1545    (defmethod testgf47 ((x (eql inst))) (list 'inst (call-next-method)))
1546    (list
1547      (testgf47 inst)
1548      (progn
1549        (defclass testclass47c (testclass47b testclass47a) ())
1550        (testgf47 inst)))))
1551((INST A) (INST B))
1552
1553;; EQL specializers on change-class'ed instances.
1554
1555; Case 1: Adding a class to a CPL.
1556(progn
1557  (defclass testclass48a () ())
1558  (defclass testclass48b () ())
1559  (defclass testclass48c (testclass48b) ())
1560  (let ((inst (make-instance 'standard-object)))
1561    (defgeneric testgf48 (x) (:method-combination list))
1562    (defmethod testgf48 list ((x testclass48a)) 'a)
1563    (defmethod testgf48 list ((x (eql inst))) 'inst)
1564    (change-class inst 'testclass48c)
1565    (list
1566      (testgf48 inst)
1567      (progn
1568        (defclass testclass48b (testclass48a) ())
1569        (testgf48 inst)))))
1570((INST) (INST A))
1571
1572; Case 2: Removing a class from a CPL.
1573(progn
1574  (defclass testclass49a () ())
1575  (defclass testclass49b (testclass49a) ())
1576  (defclass testclass49c (testclass49b) ())
1577  (let ((inst (make-instance 'standard-object)))
1578    (defgeneric testgf49 (x) (:method-combination list))
1579    (defmethod testgf49 list ((x testclass49a)) 'a)
1580    (defmethod testgf49 list ((x (eql inst))) 'inst)
1581    (change-class inst 'testclass49c)
1582    (list
1583      (testgf49 inst)
1584      (progn
1585        (defclass testclass49b () ())
1586        (testgf49 inst)))))
1587((INST A) (INST))
1588
1589; Case 3: Reordering a CPL.
1590(progn
1591  (defclass testclass50a () ())
1592  (defclass testclass50b () ())
1593  (defclass testclass50c (testclass50a testclass50b) ())
1594  (let ((inst (make-instance 'standard-object)))
1595    (defgeneric testgf50 (x))
1596    (defmethod testgf50 ((x testclass50a)) 'a)
1597    (defmethod testgf50 ((x testclass50b)) 'b)
1598    (defmethod testgf50 ((x (eql inst))) (list 'inst (call-next-method)))
1599    (change-class inst 'testclass50c)
1600    (list
1601      (testgf50 inst)
1602      (progn
1603        (defclass testclass50c (testclass50b testclass50a) ())
1604        (testgf50 inst)))))
1605((INST A) (INST B))
1606
1607
1608;;; ensure-generic-function
1609;;; <http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/fun_ensure-ge_ric-function.html>
1610(ensure-generic-function 'car) error
1611(ensure-generic-function 'defclass) error
1612(ensure-generic-function 'tagbody) error
1613
1614(let ((f 'egf-fun))
1615  (when (fboundp f) (fmakunbound f))
1616  (list
1617   (fboundp f)
1618   (typep (ensure-generic-function f) 'generic-function)
1619   (typep (ensure-generic-function f) 'generic-function)
1620   (typep (symbol-function f) 'generic-function)))
1621(nil t t t)
1622
1623(let ((f 'egf-fun))
1624  (when (fboundp f) (fmakunbound f))
1625  (list
1626   (fboundp f)
1627   (typep (ensure-generic-function f :lambda-list '(a b c))
1628          'generic-function)
1629   ;; Test of incongruent generic function lambda list when no
1630   ;; methods exist
1631   (typep (ensure-generic-function f :lambda-list '(x y))
1632          'generic-function)
1633   (typep (symbol-function f) 'generic-function)))
1634(nil t t t)
1635
1636(let ((f 'egf-fun))
1637  (when (fboundp f) (fmakunbound f))
1638  (list
1639   (fboundp f)
1640   (typep (ensure-generic-function f :lambda-list '(a b c))
1641          'generic-function)
1642   (typep (eval `(defmethod ,f ((a t)(b t)(c t)) (list a b c)))
1643          'standard-method)))
1644(nil t t)
1645
1646;; Test of incongruent generic function lambda list when
1647;; some methods do exist
1648(ensure-generic-function 'egf-fun :lambda-list '(x y))
1649error
1650
1651;; forward reference (GCL ansi test)
1652(let ((c1 (gensym)) (c2 (gensym)))
1653  (let ((class1 (eval `(defclass ,c1 (,c2) nil))))
1654    (if (not (typep class1 'class))
1655        1
1656        (let ((class2 (eval `(defclass ,c2 nil nil))))
1657          (if (not (typep class2 'class))
1658              2
1659              (let ((i1 (make-instance c1))
1660                    (i2 (make-instance c2)))
1661                (cond
1662                  ((not (typep i1 c1))     3)
1663                  ((not (typep i1 class1)) 4)
1664                  ((not (typep i1 c2))     5)
1665                  ((not (typep i1 class2)) 6)
1666                  ((typep i2 c1)           7)
1667                  ((typep i2 class1)       8)
1668                  ((not (typep i2 c2))     9)
1669                  ((not (typep i2 class2)) 10)
1670                  (t 'good))))))))
1671good
1672
1673(let ((c1 (gensym)) (c2 (gensym)) (c3 (gensym)))
1674  (let ((class1 (eval `(defclass ,c1 (,c2 ,c3) nil))))
1675    (if (not (typep class1 'class))
1676        1
1677        (let ((class2 (eval `(defclass ,c2 nil nil))))
1678          (if (not (typep class2 'class))
1679              2
1680              (let ((class3 (eval `(defclass ,c3 nil nil))))
1681                (if (not (typep class3 'class))
1682                    3
1683                    (let ((i1 (make-instance c1))
1684                          (i2 (make-instance c2))
1685                          (i3 (make-instance c3)))
1686                      (cond
1687                        ((not (typep i1 c1))     4)
1688                        ((not (typep i1 class1)) 5)
1689                        ((not (typep i1 c2))     6)
1690                        ((not (typep i1 class2)) 7)
1691                        ((not (typep i1 c3))     8)
1692                        ((not (typep i1 class3)) 9)
1693                        ((typep i2 c1)           10)
1694                        ((typep i2 class1)       11)
1695                        ((typep i3 c1)           12)
1696                        ((typep i3 class1)       13)
1697                        ((not (typep i2 c2))     14)
1698                        ((not (typep i2 class2)) 15)
1699                        ((not (typep i3 c3))     16)
1700                        ((not (typep i3 class3)) 17)
1701                        ((typep i2 c3)           18)
1702                        ((typep i2 class3)       19)
1703                        ((typep i3 c2)           20)
1704                        ((typep i3 class2)       21)
1705                        (t 'good))))))))))
1706good
1707
1708(let ((c1 (gensym)) (c2 (gensym)) (c3 (gensym)))
1709  (let ((class1 (eval `(defclass ,c1 (,c2) nil))))
1710    (if (not (typep class1 'class))
1711        1
1712        (let ((class2 (eval `(defclass ,c2 (,c3) nil))))
1713          (if (not (typep class2 'class))
1714              2
1715              (let ((class3 (eval `(defclass ,c3 nil nil))))
1716                (if (not (typep class3 'class))
1717                    3
1718                    (let ((i1 (make-instance c1))
1719                          (i2 (make-instance c2))
1720                          (i3 (make-instance c3)))
1721                      (cond
1722                        ((not (typep i1 c1))     4)
1723                        ((not (typep i1 class1)) 5)
1724                        ((not (typep i1 c2))     6)
1725                        ((not (typep i1 class2)) 7)
1726                        ((not (typep i1 c3))     8)
1727                        ((not (typep i1 class3)) 9)
1728                        ((typep i2 c1)           10)
1729                        ((typep i2 class1)       11)
1730                        ((typep i3 c1)           12)
1731                        ((typep i3 class1)       13)
1732                        ((not (typep i2 c2))     14)
1733                        ((not (typep i2 class2)) 15)
1734                        ((not (typep i3 c3))     16)
1735                        ((not (typep i3 class3)) 17)
1736                        ((not (typep i2 c3))     18)
1737                        ((not (typep i2 class3)) 19)
1738                        ((typep i3 c2)           20)
1739                        ((typep i3 class2)       21)
1740                        (t 'good))))))))))
1741good
1742
1743(block nil
1744  (let ((c1 (gensym)) (c2 (gensym)) (c3 (gensym)) (c4 (gensym)) (c5 (gensym)))
1745    (unless (typep (eval `(defclass ,c4 nil nil)) 'class)
1746      (return 1))
1747    (unless (typep (eval `(defclass ,c5 nil nil)) 'class)
1748      (return 2))
1749    (unless (typep (eval `(defclass ,c1 (,c2 ,c3) nil)) 'class)
1750      (return 3))
1751    (unless (typep (eval `(defclass ,c2 (,c4 ,c5) nil)) 'class)
1752      (return 4))
1753    (eval `(progn
1754             (defclass ,c3 (,c5 ,c4) nil)
1755             (make-instance ',c1)))))
1756error
1757
1758(progn
1759  (defclass class-0203 () ((a :allocation :class) (b :allocation :instance)))
1760  (defclass class-0204 (class-0203) (c d))
1761  (let ((c1 (make-instance 'class-0203)) (c2 (make-instance 'class-0204)))
1762    (list
1763     :bound (slot-boundp c1 'a) (slot-boundp c1 'b)
1764     (slot-boundp c2 'a) (slot-boundp c2 'b)
1765     (slot-boundp c2 'c) (slot-boundp c2 'd)
1766     (setf (slot-value c1 'a) 'x)
1767     :bound (slot-boundp c1 'a) (slot-boundp c1 'b)
1768     (slot-boundp c2 'a) (slot-boundp c2 'b)
1769     (slot-boundp c2 'c) (slot-boundp c2 'd)
1770     (slot-value c1 'a)
1771     (slot-value c2 'a)
1772     (eq (slot-makunbound c1 'a) c1)
1773     :bound (slot-boundp c1 'a) (slot-boundp c1 'b)
1774     (slot-boundp c2 'a) (slot-boundp c2 'b)
1775     (slot-boundp c2 'c) (slot-boundp c2 'd))))
1776(:bound nil nil nil nil nil nil
1777 x
1778 :bound t nil t nil nil nil
1779 x x
1780 t
1781 :bound nil nil nil nil nil nil)
1782
1783(progn
1784  (defclass class-0206a () ((a :allocation :instance) (b :allocation :class)))
1785  (defclass class-0206b (class-0206a)
1786    ((a :allocation :class) (b :allocation :instance)))
1787  (let ((c1 (make-instance 'class-0206a)) (c2 (make-instance 'class-0206b)))
1788    (list
1789     :bound (slot-boundp c1 'a) (slot-boundp c1 'b)
1790     (slot-boundp c2 'a) (slot-boundp c2 'b)
1791     (setf (slot-value c1 'a) 'x)
1792     (setf (slot-value c1 'b) 'y)
1793     :bound (slot-boundp c1 'a) (slot-boundp c1 'b)
1794     (slot-boundp c2 'a) (slot-boundp c2 'b)
1795     :value-1
1796     (slot-value c1 'a) (slot-value c1 'b)
1797     (progn (slot-makunbound c1 'a)
1798            (slot-makunbound c1 'b)
1799            (setf (slot-value c2 'a) 'x))
1800     (setf (slot-value c2 'b) 'y)
1801     :bound (slot-boundp c1 'a) (slot-boundp c1 'b)
1802     (slot-boundp c2 'a) (slot-boundp c2 'b)
1803     :value-2
1804     (slot-value c2 'a) (slot-value c2 'b)
1805     (progn (slot-makunbound c2 'a)
1806            (slot-makunbound c2 'b)
1807            nil))))
1808(:bound nil nil nil nil
1809 x y
1810 :bound t t nil nil
1811 :value-1 x y
1812 x y
1813 :bound nil nil t t
1814 :value-2 x y
1815 nil)
1816
1817(let* ((c (defclass reinit-class-01 ()
1818            ((a :initarg :a) (b :initarg :b))))
1819       (m (defmethod reinitialize-instance :after ((instance reinit-class-01)
1820                                                   &rest initargs
1821                                                   &key (x nil x-p))
1822            (declare (ignore initargs))
1823            (when x-p (setf (slot-value instance 'a) x))
1824            instance)))
1825  (eq m (find-method #'reinitialize-instance '(:after) (list c))))
1826T
1827
1828(let* ((obj (make-instance 'reinit-class-01))
1829       (obj2 (reinitialize-instance obj :a 1 :b 3)))
1830  (list (eq obj obj2) (slot-value obj2 'a) (slot-value obj2 'b)))
1831(t 1 3)
1832
1833(let* ((obj (make-instance 'reinit-class-01 :a 10 :b 20))
1834       (obj2 (reinitialize-instance obj :x 3)))
1835  (list (eq obj obj2) (slot-value obj2 'a) (slot-value obj2 'b)))
1836(t 3 20)
1837
1838(let* ((obj (make-instance 'reinit-class-01 :a 10 :b 20))
1839       (obj2 (reinitialize-instance obj :x 3 :x 100)))
1840  (list (eq obj obj2) (slot-value obj2 'a) (slot-value obj2 'b)))
1841(t 3 20)
1842
1843(let* ((obj (make-instance 'reinit-class-01 :a 10 :b 20))
1844       (obj2 (reinitialize-instance obj :x 3 :garbage 100)))
1845  (list (eq obj obj2) (slot-value obj2 'a) (slot-value obj2 'b)))
1846error
1847
1848;; Check that invalid generic-function options are rejected.
1849(defgeneric foo126 (x y) (:lambda-list x))
1850ERROR
1851(defgeneric foo127 (x y) (:declarations (optimize (speed 3))))
1852ERROR
1853
1854(let ((gf1 (defgeneric no-app-meth-gf-01 ()))
1855      (gf2 (defgeneric no-app-meth-gf-02 (x)))
1856      (gf3 (defgeneric no-app-meth-gf-03 (x y))))
1857  (defmethod no-applicable-method ((x (eql gf1)) &rest args)
1858    (list 'no-applicable-method args))
1859  (defmethod no-applicable-method ((x (eql gf2)) &rest args)
1860    (list 'no-applicable-method args))
1861  (defmethod no-applicable-method ((x (eql gf3)) &rest args)
1862    (list 'no-applicable-method args))
1863  (list (no-app-meth-gf-01)
1864        (no-app-meth-gf-02 (cons 'a 'b))
1865        (no-app-meth-gf-03 (cons 'a 'b) (cons 'c 'd))))
1866((NO-APPLICABLE-METHOD nil)
1867 (NO-APPLICABLE-METHOD ((A . B)))
1868 (NO-APPLICABLE-METHOD ((A . B) (C . D))))
1869
1870#+CLISP
1871(let ((gf1 (defgeneric no-prim-meth-gf-01 ()))
1872      (gf2 (defgeneric no-prim-meth-gf-02 (x)))
1873      (gf3 (defgeneric no-prim-meth-gf-03 (x y))))
1874  (defmethod no-prim-meth-gf-01 :around ()
1875    (list :around (call-next-method)))
1876  (defmethod no-primary-method ((x (eql gf1)) &rest args)
1877    (list 'no-primary-method args))
1878  (defmethod no-prim-meth-gf-02 :around ((x t))
1879    (list :around x (call-next-method)))
1880  (defmethod no-primary-method ((x (eql gf2)) &rest args)
1881    (list 'no-primary-method args))
1882  (defmethod no-prim-meth-gf-03 :around ((x t) (y t))
1883    (list :around x y (call-next-method)))
1884  (defmethod no-primary-method ((x (eql gf3)) &rest args)
1885    (list 'no-primary-method args))
1886  (list (no-prim-meth-gf-01)
1887        (no-prim-meth-gf-02 (cons 'a 'b))
1888        (no-prim-meth-gf-03 (cons 'a 'b) (cons 'c 'd))))
1889#+CLISP
1890((NO-PRIMARY-METHOD nil)
1891 (NO-PRIMARY-METHOD ((A . B)))
1892 (NO-PRIMARY-METHOD ((A . B) (C . D))))
1893
1894
1895;;; Method combinations
1896
1897;; Standard method combination
1898
1899(progn
1900  (defgeneric test-mc-standard (x)
1901    (:method ((x string)) (cons 'string (call-next-method)))
1902    (:method ((x t)) x))
1903  (list (test-mc-standard 1)
1904        (test-mc-standard "a")))
1905(1 (STRING . "a"))
1906
1907; See also the hgen test above.
1908
1909(progn
1910  (defgeneric test-mc-standard-bad-qualifiers (x y))
1911  (defmethod test-mc-standard-bad-qualifiers ((x integer) (y integer)) (+ x y))
1912  (defmethod test-mc-standard-bad-qualifiers ((x float) (y float)) (+ x y))
1913  (defmethod test-mc-standard-bad-qualifiers :beffor ((x float) (y float))
1914    (format t "x = ~S, y = ~S~%" x y))
1915  t)
1916#+(or CLISP CMU LISPWORKS) ERROR #+(or GCL ALLEGRO SBCL OpenMCL) T #-(or CLISP GCL ALLEGRO CMU SBCL OpenMCL LISPWORKS) UNKNOWN
1917
1918(progn
1919  (defgeneric test-mc-standard-bad1 (x y))
1920  (defmethod test-mc-standard-bad1 ((x real) (y real)) (+ x y))
1921  (defmethod test-mc-standard-bad1 :after :before ((x integer) (y integer))
1922    (* x y))
1923  t)
1924#+(or CLISP ALLEGRO CMU LISPWORKS) ERROR #+(or SBCL OpenMCL) T #-(or CLISP ALLEGRO CMU SBCL OpenMCL LISPWORKS) UNKNOWN
1925
1926(progn
1927  (defgeneric test-mc-standard-bad2 (x y))
1928  (defmethod test-mc-standard-bad2 ((x real) (y real)) (+ x y))
1929  (defmethod test-mc-standard-bad2 :before ((x integer) (y integer))
1930    (floor (call-next-method)))
1931  (test-mc-standard-bad2 3 4))
1932ERROR
1933
1934(progn
1935  (defgeneric test-mc-standard-bad3 (x y))
1936  (defmethod test-mc-standard-bad3 ((x real) (y real)) (+ x y))
1937  (defmethod test-mc-standard-bad3 :after ((x integer) (y integer))
1938    (floor (call-next-method)))
1939  (test-mc-standard-bad3 3 4))
1940ERROR
1941
1942(progn
1943  (defgeneric test-mc-standard-bad4 (x y)
1944    (:method-combination standard :most-specific-last)))
1945ERROR
1946
1947;; Built-in method combination
1948
1949(progn
1950  (defgeneric test-mc-progn (x s)
1951    (:method-combination progn)
1952    (:method progn ((x string) s) (vector-push-extend 'string s))
1953    (:method progn ((x t) s) (vector-push-extend 't s))
1954    (:method :around ((x number) s)
1955             (vector-push-extend 'number s) (call-next-method)))
1956  (list (let ((s (make-array 10 :adjustable t :fill-pointer 0)))
1957          (test-mc-progn 1 s)
1958          s)
1959        (let ((s (make-array 10 :adjustable t :fill-pointer 0)))
1960          (test-mc-progn "a" s)
1961          s)))
1962(#(NUMBER T) #(STRING T))
1963
1964; Test checking of qualifiers.
1965(progn
1966  (defgeneric test-mc-append-1 (x)
1967    (:method-combination append)
1968    (:method ((x string)) (list (length x)))
1969    (:method ((x vector)) (list (array-element-type x))))
1970  t)
1971#+(or CLISP CMU LISPWORKS) ERROR #+(or ALLEGRO SBCL OpenMCL) T #-(or CLISP ALLEGRO CMU SBCL OpenMCL LISPWORKS) UNKNOWN
1972
1973; Test ANSI CL 7.6.6.4.
1974(progn
1975  (defgeneric test-mc-append-2 (x)
1976    (:method-combination append)
1977    (:method append ((x string)) (list (length x)))
1978    (:method append ((x vector)) (list (type-of (aref x 0))))
1979    (:method :around ((x string)) (list #\" (call-next-method) #\"))
1980    (:method :around ((x vector)) (coerce (call-next-method) 'vector)))
1981  (test-mc-append-2 "abc"))
1982(#\" #(3 STANDARD-CHAR) #\")
1983
1984; Check that :most-specific-last affects only the order of the primary methods.
1985(progn
1986  (defgeneric test-mc-append-3 (x)
1987    (:method-combination append :most-specific-last)
1988    (:method append ((x string)) (list (length x)))
1989    (:method append ((x vector)) (list (type-of (aref x 0))))
1990    (:method :around ((x string)) (list #\" (call-next-method) #\"))
1991    (:method :around ((x vector)) (coerce (call-next-method) 'vector)))
1992  (test-mc-append-3 "abc"))
1993(#\" #(STANDARD-CHAR 3) #\")
1994
1995;; Short-form method combination
1996
1997; Syntax
1998(define-method-combination mc01 :documentation :operator)
1999ERROR
2000
2001; Syntax
2002(define-method-combination mc02 :documentation nil)
2003ERROR
2004
2005; Syntax
2006(define-method-combination mc03 :documentation "foo" :documentation "bar")
2007ERROR
2008
2009; Syntax
2010(define-method-combination mc04
2011  :identity-with-one-argument nil :operator list :documentation)
2012ERROR
2013
2014(define-method-combination mc05
2015  :identity-with-one-argument nil :operator list :documentation "test")
2016MC05
2017
2018; Check that the operator is called.
2019(progn
2020  (defgeneric test-mc05-1 (x)
2021    (:method mc05 ((x real)) 'real)
2022    (:method mc05 ((x integer)) 'integer)
2023    (:method mc05 ((x number)) 'number)
2024    (:method-combination mc05))
2025  (test-mc05-1 3))
2026(INTEGER REAL NUMBER)
2027
2028; Check that the method-combination arguments are unevaluated.
2029(progn
2030  (defgeneric test-mc05-2 (x)
2031    (:method mc05 ((x real)) 'real)
2032    (:method mc05 ((x integer)) 'integer)
2033    (:method mc05 ((x number)) 'number)
2034    (:method-combination mc05 (intern "MOST-SPECIFIC-LAST" "KEYWORD")))
2035  (test-mc05-2 3))
2036ERROR
2037
2038; Check that passing :most-specific-last as method-combination argument works.
2039(progn
2040  (defgeneric test-mc05-3 (x)
2041    (:method mc05 ((x real)) 'real)
2042    (:method mc05 ((x integer)) 'integer)
2043    (:method mc05 ((x number)) 'number)
2044    (:method-combination mc05 :most-specific-last))
2045  (test-mc05-3 3))
2046(NUMBER REAL INTEGER)
2047
2048; Check that the operator is also called if there is just one method.
2049(progn
2050  (defgeneric test-mc05-4 (x)
2051    (:method mc05 ((x real)) 'real)
2052    (:method-combination mc05 :most-specific-last))
2053  (test-mc05-4 3))
2054(REAL)
2055
2056; Check that nil is an invalid method-combination argument.
2057(progn
2058  (defgeneric test-mc05-5 (x)
2059    (:method mc05 ((x real)) 'real)
2060    (:method-combination mc05 nil)))
2061ERROR
2062
2063; Check that extra method-combination arguments are rejected.
2064(progn
2065  (defgeneric test-mc05-6 (x)
2066    (:method mc05 ((x real)) 'real)
2067    (:method-combination mc05 :most-specific-first junk)))
2068ERROR
2069
2070(define-method-combination mc06
2071  :identity-with-one-argument t :operator list :documentation "test")
2072MC06
2073
2074; Check that the operator is not called if there is just one method.
2075(progn
2076  (defgeneric test-mc06-1 (x)
2077    (:method mc06 ((x real)) 'real)
2078    (:method-combination mc06 :most-specific-last))
2079  (test-mc06-1 3))
2080REAL
2081
2082;; Long-form method combination
2083
2084; Example from CLHS
2085(progn
2086  (defun positive-integer-qualifier-p (method-qualifiers)
2087    (and (= (length method-qualifiers) 1)
2088         (typep (first method-qualifiers) '(integer 0 *))))
2089  (define-method-combination example-method-combination ()
2090    ((method-list positive-integer-qualifier-p))
2091    `(PROGN ,@(mapcar #'(lambda (method) `(CALL-METHOD ,method))
2092                      (stable-sort method-list #'<
2093                                   :key #'(lambda (method)
2094                                            (first (method-qualifiers
2095                                                    method)))))))
2096  (defgeneric mc-test-piq (p1 p2 s)
2097    (:method-combination example-method-combination)
2098    (:method 1 ((p1 t) (p2 t) s) (vector-push-extend (list 1 p1 p2) s))
2099    (:method 4 ((p1 t) (p2 t) s) (vector-push-extend (list 4 p1 p2) s))
2100    (:method 2 ((p1 t) (p2 t) s) (vector-push-extend (list 2 p1 p2) s))
2101    (:method 3 ((p1 t) (p2 t) s) (vector-push-extend (list 3 p1 p2) s)))
2102  (let ((s (make-array 10 :adjustable t :fill-pointer 0)))
2103    (mc-test-piq 1 2 s)
2104    s))
2105;#((1 1 2) (2 1 2) (3 1 2) (4 1 2))
2106; ANSI CL: "If the two methods play the same role and their order matters,
2107;           an error is signaled."
2108ERROR
2109
2110; Example with :arguments.
2111(progn
2112  (define-method-combination w-args ()
2113    ((method-list *))
2114    (:arguments arg1 arg2 &aux (extra :extra))
2115    `(PROGN ,@(mapcar #'(lambda (method) `(CALL-METHOD ,method)) method-list)))
2116  (defgeneric mc-test-w-args (p1 p2 s)
2117    (:method-combination w-args)
2118    (:method ((p1 number) (p2 t) s)
2119      (vector-push-extend (list 'number p1 p2) s))
2120    (:method ((p1 string) (p2 t) s)
2121      (vector-push-extend (list 'string p1 p2) s))
2122    (:method ((p1 t) (p2 t) s) (vector-push-extend (list t p1 p2) s)))
2123  (let ((s (make-array 10 :adjustable t :fill-pointer 0)))
2124    (mc-test-w-args 1 2 s)
2125    s))
2126#((NUMBER 1 2) (T 1 2))
2127
2128; Syntax
2129(define-method-combination mc11 ())
2130ERROR
2131
2132; Syntax
2133(define-method-combination mc12 () ())
2134MC12
2135
2136; Syntax
2137(define-method-combination mc13 () () (:arguments order &aux &key))
2138ERROR
2139
2140; Syntax
2141(define-method-combination mc14 () () (:arguments &whole))
2142ERROR
2143
2144(define-method-combination mc15 () () (:arguments order))
2145MC15
2146
2147; Syntax
2148(define-method-combination mc16 () () (:generic-function))
2149ERROR
2150
2151; Syntax
2152(define-method-combination mc17 () () (:generic-function gf1 gf2))
2153ERROR
2154
2155; Syntax
2156(define-method-combination mc18 () () (:generic-function (gf)))
2157ERROR
2158
2159(define-method-combination mc19 () () (:generic-function gf))
2160MC19
2161
2162; Syntax
2163(define-method-combination mc20 () (a))
2164ERROR
2165
2166; Syntax
2167(define-method-combination mc21 () ((3)))
2168ERROR
2169
2170; Syntax
2171(define-method-combination mc22 () ((a)))
2172ERROR
2173
2174(define-method-combination mc23 () ((a *)))
2175MC23
2176
2177; Check that it's allowed (although redundant) to have multiple catch-all
2178; method groups.
2179(define-method-combination mc24 () ((a *) (b *))
2180  `(PROGN (CALL-METHOD ,(first a)) (CALL-METHOD ,(first b))))
2181MC24
2182
2183; Check that an error is signaled if there is no applicable method.
2184(progn
2185  (define-method-combination mc25 () ((all ()))
2186    `(LIST 'RESULT ,@(mapcar #'(lambda (method) `(CALL-METHOD ,method)) all)))
2187  (defgeneric test-mc25 (x)
2188    (:method-combination mc25))
2189  (test-mc25 7))
2190ERROR
2191
2192; Check that no error is signaled if there are applicable methods but the
2193; method combination chooses to ignore them.
2194(progn
2195  (define-method-combination mc26 () ((normal ()) (ignored (:ignore)))
2196    `(LIST 'RESULT ,@(mapcar #'(lambda (method) `(CALL-METHOD ,method)) normal)))
2197  (defgeneric test-mc26 (x)
2198    (:method-combination mc26)
2199    (:method :ignore ((x number)) (/ 0)))
2200  (test-mc26 7))
2201(RESULT)
2202
2203; Check that a qualifier-pattern does not match qualifier lists that are
2204; subsets.
2205(progn
2206  (define-method-combination mc27 () ((normal ()) (ignored (:ignore :unused)))
2207    `(LIST 'RESULT ,@(mapcar #'(lambda (method) `(CALL-METHOD ,method)) normal)))
2208  (defgeneric test-mc27 (x)
2209    (:method-combination mc27)
2210    (:method :ignore ((x number)) (/ 0)))
2211  (test-mc27 7))
2212ERROR
2213
2214; Check that multiple qualifier-patterns act as an OR.
2215(progn
2216  (define-method-combination mc28 () ((normal ()) (ignored (:ignore) (:unused)))
2217    `(LIST 'RESULT ,@(mapcar #'(lambda (method) `(CALL-METHOD ,method)) normal)))
2218  (defgeneric test-mc28 (x)
2219    (:method-combination mc28)
2220    (:method :ignore ((x number)) (/ 0)))
2221  (test-mc28 7))
2222(RESULT)
2223
2224; Check that catch-all method groups don't comprise methods that are already
2225; matched by earlier method groups.
2226(progn
2227  (define-method-combination mc29 () ((ignored (:ignore) (:unused)) (other *))
2228    `(LIST 'RESULT ,@(mapcar #'(lambda (method) `(CALL-METHOD ,method)) other)))
2229  (defgeneric test-mc29 (x)
2230    (:method-combination mc29)
2231    (:method :ignore ((x number)) (/ 0)))
2232  (test-mc29 7))
2233(RESULT)
2234
2235; Check the simultaneous presence of options and :arguments.
2236(define-method-combination mc50 (opt1 opt2) ((all *))
2237  (:arguments &whole whole arg1 arg2 &rest more-args)
2238  `(LIST ',opt1 ',opt2 'RESULT ,whole ,arg1 ,arg2 ,more-args))
2239MC50
2240
2241(defgeneric test-mc50-1 (x)
2242  (:method-combination mc50 xyz))
2243ERROR
2244
2245(progn
2246  (defgeneric test-mc50-2 (x)
2247    (:method-combination mc50 xyz "foo")
2248    (:method ((x integer)) (/ 0)))
2249  (test-mc50-2 7))
2250(XYZ "foo" RESULT (7) 7 NIL ())
2251
2252(progn
2253  (defgeneric test-mc50-3 (x y z)
2254    (:method-combination mc50 xyz "bar")
2255    (:method ((x t) (y t) (z t)) (/ 0)))
2256  (test-mc50-3 'a 'b 'c))
2257(XYZ "bar" RESULT (A B C) A B NIL)
2258
2259; Check the simultaneous presence of options (with &optional and &rest) and
2260; :arguments (with &key).
2261(define-method-combination mc51 (opt1 &optional opt2 &rest more-opts) ((all *))
2262  (:arguments &whole whole arg1 &key test test-not)
2263  `(LIST ',opt1 ',opt2 ',more-opts 'RESULT ,whole ,arg1 ,test ,test-not))
2264MC51
2265
2266(defgeneric test-mc51-1 (x)
2267  (:method-combination mc51))
2268ERROR
2269
2270(progn
2271  (defgeneric test-mc51-2 (x)
2272    (:method-combination mc51 "xyz")
2273    (:method ((x integer)) (/ 0)))
2274  (test-mc51-2 7))
2275("xyz" NIL NIL RESULT (7) 7 NIL NIL)
2276
2277(progn
2278  (defgeneric test-mc51-3 (x)
2279    (:method-combination mc51 "xyz" "uvw")
2280    (:method ((x integer)) (/ 0)))
2281  (test-mc51-3 7))
2282("xyz" "uvw" NIL RESULT (7) 7 NIL NIL)
2283
2284(progn
2285  (defgeneric test-mc51-4 (x)
2286    (:method-combination mc51 "xyz" "uvw" :foo :bar)
2287    (:method ((x integer)) (/ 0)))
2288  (test-mc51-4 7))
2289("xyz" "uvw" (:FOO :BAR) RESULT (7) 7 NIL NIL)
2290
2291(progn
2292  (defgeneric test-mc51-5 (x &key test test-not key predicate)
2293    (:method-combination mc51 "xyz" "uvw" :foo :bar)
2294    (:method ((x integer) &key predicate test test-not key) (/ 0)))
2295  (test-mc51-5 7 :key 'FIRST :TEST-NOT 'EQUAL))
2296("xyz" "uvw" (:FOO :BAR) RESULT (7 :KEY FIRST :TEST-NOT EQUAL) 7 NIL EQUAL)
2297
2298; Check :arguments with no arguments.
2299(define-method-combination mc60 (opt1 &optional (opt2 "def")) ((all *))
2300  (:arguments)
2301  `(LIST ',opt1 ',opt2 'RESULT (CALL-METHOD ,(first all))))
2302MC60
2303
2304(progn
2305  (defgeneric test-mc60-1 ()
2306    (:method-combination mc60 "xyz")
2307    (:method () '()))
2308  (test-mc60-1))
2309("xyz" "def" RESULT ())
2310
2311(progn
2312  (defgeneric test-mc60-2 (x y)
2313    (:method-combination mc60 "xyz")
2314    (:method (x y) (list x y)))
2315  (test-mc60-2 'a 'b))
2316("xyz" "def" RESULT (A B))
2317
2318(progn
2319  (defgeneric test-mc60-3 (&optional x y)
2320    (:method-combination mc60 "xyz")
2321    (:method (&optional x y) (list x y)))
2322  (test-mc60-3 'a))
2323("xyz" "def" RESULT (A NIL))
2324
2325(progn
2326  (defgeneric test-mc60-4 (&rest x)
2327    (:method-combination mc60 "xyz")
2328    (:method (&rest x) x))
2329  (test-mc60-4 'a 'b))
2330("xyz" "def" RESULT (A B))
2331
2332; Check :arguments with only required arguments.
2333(define-method-combination mc61 (opt1 &optional (opt2 "def")) ((all *))
2334  (:arguments a1 a2)
2335  `(LIST ',opt1 ',opt2 'RESULT ,a1 ,a2 (CALL-METHOD ,(first all))))
2336MC61
2337
2338(progn
2339  (defgeneric test-mc61-1 (x)
2340    (:method-combination mc61 "xyz")
2341    (:method (x) (list x)))
2342  (test-mc61-1 'a))
2343("xyz" "def" RESULT A NIL (A))
2344
2345(progn
2346  (defgeneric test-mc61-2 (x y)
2347    (:method-combination mc61 "xyz")
2348    (:method (x y) (list x y)))
2349  (test-mc61-2 'a 'b))
2350("xyz" "def" RESULT A B (A B))
2351
2352(progn
2353  (defgeneric test-mc61-3 (x y z)
2354    (:method-combination mc61 "xyz")
2355    (:method (x y z) (list x y z)))
2356  (test-mc61-3 'a 'b 'c))
2357("xyz" "def" RESULT A B (A B C))
2358
2359(progn
2360  (defgeneric test-mc61-4 (x &optional y z)
2361    (:method-combination mc61 "xyz")
2362    (:method (x &optional y z) (list x y z)))
2363  (list (test-mc61-4 'a) (test-mc61-4 'a 'b) (test-mc61-4 'a 'b 'c)))
2364(("xyz" "def" RESULT A NIL (A NIL NIL))
2365 ("xyz" "def" RESULT A NIL (A B NIL))
2366 ("xyz" "def" RESULT A NIL (A B C)))
2367
2368(progn
2369  (defgeneric test-mc61-5 (x y &optional z u)
2370    (:method-combination mc61 "xyz")
2371    (:method (x y &optional z u) (list x y z u)))
2372  (list (test-mc61-5 'a 'b) (test-mc61-5 'a 'b 'c) (test-mc61-5 'a 'b 'c 'd)))
2373(("xyz" "def" RESULT A B (A B NIL NIL))
2374 ("xyz" "def" RESULT A B (A B C NIL))
2375 ("xyz" "def" RESULT A B (A B C D)))
2376
2377(progn
2378  (defgeneric test-mc61-6 (x y z &optional u v)
2379    (:method-combination mc61 "xyz")
2380    (:method (x y z &optional u v) (list x y z u v)))
2381  (list (test-mc61-6 'a 'b 'c) (test-mc61-6 'a 'b 'c 'd) (test-mc61-6 'a 'b 'c 'd 'e)))
2382(("xyz" "def" RESULT A B (A B C NIL NIL))
2383 ("xyz" "def" RESULT A B (A B C D NIL))
2384 ("xyz" "def" RESULT A B (A B C D E)))
2385
2386(progn
2387  (defgeneric test-mc61-7 (x &rest y)
2388    (:method-combination mc61 "xyz")
2389    (:method (x &rest y) (list* x y)))
2390  (list (test-mc61-7 'a) (test-mc61-7 'a 'b) (test-mc61-7 'a 'b 'c)))
2391(("xyz" "def" RESULT A NIL (A))
2392 ("xyz" "def" RESULT A NIL (A B))
2393 ("xyz" "def" RESULT A NIL (A B C)))
2394
2395(progn
2396  (defgeneric test-mc61-8 (x y &rest z)
2397    (:method-combination mc61 "xyz")
2398    (:method (x y &rest z) (list* x y z)))
2399  (list (test-mc61-8 'a 'b) (test-mc61-8 'a 'b 'c) (test-mc61-8 'a 'b 'c 'd)))
2400(("xyz" "def" RESULT A B (A B))
2401 ("xyz" "def" RESULT A B (A B C))
2402 ("xyz" "def" RESULT A B (A B C D)))
2403
2404(progn
2405  (defgeneric test-mc61-9 (x y z &rest u)
2406    (:method-combination mc61 "xyz")
2407    (:method (x y z &rest u) (list* x y z u)))
2408  (list (test-mc61-9 'a 'b 'c) (test-mc61-9 'a 'b 'c 'd) (test-mc61-9 'a 'b 'c 'd 'e)))
2409(("xyz" "def" RESULT A B (A B C))
2410 ("xyz" "def" RESULT A B (A B C D))
2411 ("xyz" "def" RESULT A B (A B C D E)))
2412
2413; Check :arguments with only optional arguments.
2414(define-method-combination mc62 (opt1 &optional (opt2 "def")) ((all *))
2415  (:arguments &optional (o1 'def1) (o2 'def2))
2416  `(LIST ',opt1 ',opt2 'RESULT ,o1 ,o2 (CALL-METHOD ,(first all))))
2417MC62
2418
2419(progn
2420  (defgeneric test-mc62-1 (x)
2421    (:method-combination mc62 "xyz")
2422    (:method (x) (list x)))
2423  (test-mc62-1 'a))
2424("xyz" "def" RESULT DEF1 DEF2 (A))
2425
2426(progn
2427  (defgeneric test-mc62-2 (x &optional y)
2428    (:method-combination mc62 "xyz")
2429    (:method (x &optional y) (list x y)))
2430  (list (test-mc62-2 'a) (test-mc62-2 'a 'b)))
2431(("xyz" "def" RESULT DEF1 DEF2 (A NIL))
2432 ("xyz" "def" RESULT B DEF2 (A B)))
2433
2434(progn
2435  (defgeneric test-mc62-3 (x &optional y z)
2436    (:method-combination mc62 "xyz")
2437    (:method (x &optional y z) (list x y z)))
2438  (list (test-mc62-3 'a) (test-mc62-3 'a 'b) (test-mc62-3 'a 'b 'c)))
2439(("xyz" "def" RESULT DEF1 DEF2 (A NIL NIL))
2440 ("xyz" "def" RESULT B DEF2 (A B NIL))
2441 ("xyz" "def" RESULT B C (A B C)))
2442
2443(progn
2444  (defgeneric test-mc62-4 (x &optional y z u)
2445    (:method-combination mc62 "xyz")
2446    (:method (x &optional y z u) (list x y z u)))
2447  (list (test-mc62-4 'a) (test-mc62-4 'a 'b) (test-mc62-4 'a 'b 'c) (test-mc62-4 'a 'b 'c 'd)))
2448(("xyz" "def" RESULT DEF1 DEF2 (A NIL NIL NIL))
2449 ("xyz" "def" RESULT B DEF2 (A B NIL NIL))
2450 ("xyz" "def" RESULT B C (A B C NIL))
2451 ("xyz" "def" RESULT B C (A B C D)))
2452
2453(progn
2454  (defgeneric test-mc62-5 (x &rest y)
2455    (:method-combination mc62 "xyz")
2456    (:method (x &rest y) (list* x y)))
2457  (list (test-mc62-5 'a) (test-mc62-5 'a 'b) (test-mc62-5 'a 'b 'c)))
2458(("xyz" "def" RESULT DEF1 DEF2 (A))
2459 ("xyz" "def" RESULT DEF1 DEF2 (A B))
2460 ("xyz" "def" RESULT DEF1 DEF2 (A B C)))
2461
2462(progn
2463  (defgeneric test-mc62-6 (x &optional y &rest z)
2464    (:method-combination mc62 "xyz")
2465    (:method (x &optional y &rest z) (list* x y z)))
2466  (list (test-mc62-6 'a) (test-mc62-6 'a 'b) (test-mc62-6 'a 'b 'c)))
2467(("xyz" "def" RESULT DEF1 DEF2 (A NIL))
2468 ("xyz" "def" RESULT B DEF2 (A B))
2469 ("xyz" "def" RESULT B DEF2 (A B C)))
2470
2471(progn
2472  (defgeneric test-mc62-7 (x &optional y z &rest u)
2473    (:method-combination mc62 "xyz")
2474    (:method (x &optional y z &rest u) (list* x y z u)))
2475  (list (test-mc62-7 'a) (test-mc62-7 'a 'b) (test-mc62-7 'a 'b 'c) (test-mc62-7 'a 'b 'c 'd)))
2476(("xyz" "def" RESULT DEF1 DEF2 (A NIL NIL))
2477 ("xyz" "def" RESULT B DEF2 (A B NIL))
2478 ("xyz" "def" RESULT B C (A B C))
2479 ("xyz" "def" RESULT B C (A B C D)))
2480
2481; Check :arguments with only rest arguments.
2482(define-method-combination mc63 (opt1 &optional (opt2 "def")) ((all *))
2483  (:arguments &rest r)
2484  `(LIST ',opt1 ',opt2 'RESULT ,r (CALL-METHOD ,(first all))))
2485MC63
2486
2487(progn
2488  (defgeneric test-mc63-1 ()
2489    (:method-combination mc63 "xyz")
2490    (:method () '()))
2491  (test-mc63-1))
2492("xyz" "def" RESULT () ())
2493
2494(progn
2495  (defgeneric test-mc63-2 (x y)
2496    (:method-combination mc63 "xyz")
2497    (:method (x y) (list x y)))
2498  (test-mc63-2 'a 'b))
2499("xyz" "def" RESULT () (A B))
2500
2501(progn
2502  (defgeneric test-mc63-3 (&optional x y)
2503    (:method-combination mc63 "xyz")
2504    (:method (&optional x y) (list x y)))
2505  (test-mc63-3 'a))
2506("xyz" "def" RESULT () (A NIL))
2507
2508(progn
2509  (defgeneric test-mc63-4 (&rest x)
2510    (:method-combination mc63 "xyz")
2511    (:method (&rest x) x))
2512  (test-mc63-4 'a 'b))
2513("xyz" "def" RESULT (A B) (A B))
2514
2515; Check :arguments with required and optional arguments.
2516(define-method-combination mc64 (opt1 &optional (opt2 "def")) ((all *))
2517  (:arguments a1 a2 &optional (o1 'def1) (o2 'def2))
2518  `(LIST ',opt1 ',opt2 'RESULT ,a1 ,a2 ,o1 ,o2 (CALL-METHOD ,(first all))))
2519MC64
2520
2521(progn
2522  (defgeneric test-mc64-1 ()
2523    (:method-combination mc64 "xyz")
2524    (:method () '()))
2525  (test-mc64-1))
2526("xyz" "def" RESULT NIL NIL DEF1 DEF2 ())
2527
2528(progn
2529  (defgeneric test-mc64-2 (x)
2530    (:method-combination mc64 "xyz")
2531    (:method (x) (list x)))
2532  (test-mc64-2 'a))
2533("xyz" "def" RESULT A NIL DEF1 DEF2 (A))
2534
2535(progn
2536  (defgeneric test-mc64-3 (x y)
2537    (:method-combination mc64 "xyz")
2538    (:method (x y) (list x y)))
2539  (test-mc64-3 'a 'b))
2540("xyz" "def" RESULT A B DEF1 DEF2 (A B))
2541
2542(progn
2543  (defgeneric test-mc64-4 (x y z)
2544    (:method-combination mc64 "xyz")
2545    (:method (x y z) (list x y z)))
2546  (test-mc64-4 'a 'b 'c))
2547("xyz" "def" RESULT A B DEF1 DEF2 (A B C))
2548
2549(progn
2550  (defgeneric test-mc64-5 (x &optional y)
2551    (:method-combination mc64 "xyz")
2552    (:method (x &optional y) (list x y)))
2553  (list (test-mc64-5 'a) (test-mc64-5 'a 'b)))
2554(("xyz" "def" RESULT A NIL DEF1 DEF2 (A NIL))
2555 ("xyz" "def" RESULT A NIL B DEF2 (A B)))
2556
2557(progn
2558  (defgeneric test-mc64-6 (x y &optional z)
2559    (:method-combination mc64 "xyz")
2560    (:method (x y &optional z) (list x y z)))
2561  (list (test-mc64-6 'a 'b) (test-mc64-6 'a 'b 'c)))
2562(("xyz" "def" RESULT A B DEF1 DEF2 (A B NIL))
2563 ("xyz" "def" RESULT A B C DEF2 (A B C)))
2564
2565(progn
2566  (defgeneric test-mc64-7 (x y z &optional u)
2567    (:method-combination mc64 "xyz")
2568    (:method (x y z &optional u) (list x y z u)))
2569  (list (test-mc64-7 'a 'b 'c) (test-mc64-7 'a 'b 'c 'd)))
2570(("xyz" "def" RESULT A B DEF1 DEF2 (A B C NIL))
2571 ("xyz" "def" RESULT A B D DEF2 (A B C D)))
2572
2573(progn
2574  (defgeneric test-mc64-8 (x &optional y z)
2575    (:method-combination mc64 "xyz")
2576    (:method (x &optional y z) (list x y z)))
2577  (list (test-mc64-8 'a) (test-mc64-8 'a 'b) (test-mc64-8 'a 'b 'c)))
2578(("xyz" "def" RESULT A NIL DEF1 DEF2 (A NIL NIL))
2579 ("xyz" "def" RESULT A NIL B DEF2 (A B NIL))
2580 ("xyz" "def" RESULT A NIL B C (A B C)))
2581
2582(progn
2583  (defgeneric test-mc64-9 (x y &optional z u)
2584    (:method-combination mc64 "xyz")
2585    (:method (x y &optional z u) (list x y z u)))
2586  (list (test-mc64-9 'a 'b) (test-mc64-9 'a 'b 'c) (test-mc64-9 'a 'b 'c 'd)))
2587(("xyz" "def" RESULT A B DEF1 DEF2 (A B NIL NIL))
2588 ("xyz" "def" RESULT A B C DEF2 (A B C NIL))
2589 ("xyz" "def" RESULT A B C D (A B C D)))
2590
2591(progn
2592  (defgeneric test-mc64-10 (x y z &optional u v)
2593    (:method-combination mc64 "xyz")
2594    (:method (x y z &optional u v) (list x y z u v)))
2595  (list (test-mc64-10 'a 'b 'c) (test-mc64-10 'a 'b 'c 'd) (test-mc64-10 'a 'b 'c 'd 'e)))
2596(("xyz" "def" RESULT A B DEF1 DEF2 (A B C NIL NIL))
2597 ("xyz" "def" RESULT A B D DEF2 (A B C D NIL))
2598 ("xyz" "def" RESULT A B D E (A B C D E)))
2599
2600(progn
2601  (defgeneric test-mc64-11 (x &optional y z u)
2602    (:method-combination mc64 "xyz")
2603    (:method (x &optional y z u) (list x y z u)))
2604  (list (test-mc64-11 'a) (test-mc64-11 'a 'b) (test-mc64-11 'a 'b 'c) (test-mc64-11 'a 'b 'c 'd)))
2605(("xyz" "def" RESULT A NIL DEF1 DEF2 (A NIL NIL NIL))
2606 ("xyz" "def" RESULT A NIL B DEF2 (A B NIL NIL))
2607 ("xyz" "def" RESULT A NIL B C (A B C NIL))
2608 ("xyz" "def" RESULT A NIL B C (A B C D)))
2609
2610(progn
2611  (defgeneric test-mc64-12 (x y &optional z u v)
2612    (:method-combination mc64 "xyz")
2613    (:method (x y &optional z u v) (list x y z u v)))
2614  (list (test-mc64-12 'a 'b) (test-mc64-12 'a 'b 'c) (test-mc64-12 'a 'b 'c 'd) (test-mc64-12 'a 'b 'c 'd 'e)))
2615(("xyz" "def" RESULT A B DEF1 DEF2 (A B NIL NIL NIL))
2616 ("xyz" "def" RESULT A B C DEF2 (A B C NIL NIL))
2617 ("xyz" "def" RESULT A B C D (A B C D NIL))
2618 ("xyz" "def" RESULT A B C D (A B C D E)))
2619
2620(progn
2621  (defgeneric test-mc64-13 (x y z &optional u v w)
2622    (:method-combination mc64 "xyz")
2623    (:method (x y z &optional u v w) (list x y z u v w)))
2624  (list (test-mc64-13 'a 'b 'c) (test-mc64-13 'a 'b 'c 'd) (test-mc64-13 'a 'b 'c 'd 'e) (test-mc64-13 'a 'b 'c 'd 'e 'f)))
2625(("xyz" "def" RESULT A B DEF1 DEF2 (A B C NIL NIL NIL))
2626 ("xyz" "def" RESULT A B D DEF2 (A B C D NIL NIL))
2627 ("xyz" "def" RESULT A B D E (A B C D E NIL))
2628 ("xyz" "def" RESULT A B D E (A B C D E F)))
2629
2630(progn
2631  (defgeneric test-mc64-14 (x &rest y)
2632    (:method-combination mc64 "xyz")
2633    (:method (x &rest y) (list* x y)))
2634  (list (test-mc64-14 'a) (test-mc64-14 'a 'b) (test-mc64-14 'a 'b 'c)))
2635(("xyz" "def" RESULT A NIL DEF1 DEF2 (A))
2636 ("xyz" "def" RESULT A NIL DEF1 DEF2 (A B))
2637 ("xyz" "def" RESULT A NIL DEF1 DEF2 (A B C)))
2638
2639(progn
2640  (defgeneric test-mc64-15 (x y &rest z)
2641    (:method-combination mc64 "xyz")
2642    (:method (x y &rest z) (list* x y z)))
2643  (list (test-mc64-15 'a 'b) (test-mc64-15 'a 'b 'c) (test-mc64-15 'a 'b 'c 'd)))
2644(("xyz" "def" RESULT A B DEF1 DEF2 (A B))
2645 ("xyz" "def" RESULT A B DEF1 DEF2 (A B C))
2646 ("xyz" "def" RESULT A B DEF1 DEF2 (A B C D)))
2647
2648(progn
2649  (defgeneric test-mc64-16 (x y z &rest u)
2650    (:method-combination mc64 "xyz")
2651    (:method (x y z &rest u) (list* x y z u)))
2652  (list (test-mc64-16 'a 'b 'c) (test-mc64-16 'a 'b 'c 'd) (test-mc64-16 'a 'b 'c 'd 'e)))
2653(("xyz" "def" RESULT A B DEF1 DEF2 (A B C))
2654 ("xyz" "def" RESULT A B DEF1 DEF2 (A B C D))
2655 ("xyz" "def" RESULT A B DEF1 DEF2 (A B C D E)))
2656
2657(progn
2658  (defgeneric test-mc64-17 (x &optional y &rest z)
2659    (:method-combination mc64 "xyz")
2660    (:method (x &optional y &rest z) (list* x y z)))
2661  (list (test-mc64-17 'a) (test-mc64-17 'a 'b) (test-mc64-17 'a 'b 'c) (test-mc64-17 'a 'b 'c 'd)))
2662(("xyz" "def" RESULT A NIL DEF1 DEF2 (A NIL))
2663 ("xyz" "def" RESULT A NIL B DEF2 (A B))
2664 ("xyz" "def" RESULT A NIL B DEF2 (A B C))
2665 ("xyz" "def" RESULT A NIL B DEF2 (A B C D)))
2666
2667(progn
2668  (defgeneric test-mc64-18 (x &optional y z &rest u)
2669    (:method-combination mc64 "xyz")
2670    (:method (x &optional y z &rest u) (list* x y z u)))
2671  (list (test-mc64-18 'a) (test-mc64-18 'a 'b) (test-mc64-18 'a 'b 'c) (test-mc64-18 'a 'b 'c 'd) (test-mc64-18 'a 'b 'c 'd 'e)))
2672(("xyz" "def" RESULT A NIL DEF1 DEF2 (A NIL NIL))
2673 ("xyz" "def" RESULT A NIL B DEF2 (A B NIL))
2674 ("xyz" "def" RESULT A NIL B C (A B C))
2675 ("xyz" "def" RESULT A NIL B C (A B C D))
2676 ("xyz" "def" RESULT A NIL B C (A B C D E)))
2677
2678(progn
2679  (defgeneric test-mc64-19 (x &optional y z u &rest v)
2680    (:method-combination mc64 "xyz")
2681    (:method (x &optional y z u &rest v) (list* x y z u v)))
2682  (list (test-mc64-19 'a) (test-mc64-19 'a 'b) (test-mc64-19 'a 'b 'c) (test-mc64-19 'a 'b 'c 'd) (test-mc64-19 'a 'b 'c 'd 'e) (test-mc64-19 'a 'b 'c 'd 'e 'f)))
2683(("xyz" "def" RESULT A NIL DEF1 DEF2 (A NIL NIL NIL))
2684 ("xyz" "def" RESULT A NIL B DEF2 (A B NIL NIL))
2685 ("xyz" "def" RESULT A NIL B C (A B C NIL))
2686 ("xyz" "def" RESULT A NIL B C (A B C D))
2687 ("xyz" "def" RESULT A NIL B C (A B C D E))
2688 ("xyz" "def" RESULT A NIL B C (A B C D E F)))
2689
2690; Check :arguments with required and rest arguments.
2691(define-method-combination mc65 (opt1 &optional (opt2 "def")) ((all *))
2692  (:arguments a1 a2 &rest r)
2693  `(LIST ',opt1 ',opt2 'RESULT ,a1 ,a2 ,r (CALL-METHOD ,(first all))))
2694MC65
2695
2696(progn
2697  (defgeneric test-mc65-1 ()
2698    (:method-combination mc65 "xyz")
2699    (:method () '()))
2700  (test-mc65-1))
2701("xyz" "def" RESULT NIL NIL () ())
2702
2703(progn
2704  (defgeneric test-mc65-2 (x)
2705    (:method-combination mc65 "xyz")
2706    (:method (x) (list x)))
2707  (test-mc65-2 'a))
2708("xyz" "def" RESULT A NIL () (A))
2709
2710(progn
2711  (defgeneric test-mc65-3 (x y)
2712    (:method-combination mc65 "xyz")
2713    (:method (x y) (list x y)))
2714  (test-mc65-3 'a 'b))
2715("xyz" "def" RESULT A B () (A B))
2716
2717(progn
2718  (defgeneric test-mc65-4 (x y z)
2719    (:method-combination mc65 "xyz")
2720    (:method (x y z) (list x y z)))
2721  (test-mc65-4 'a 'b 'c))
2722("xyz" "def" RESULT A B () (A B C))
2723
2724(progn
2725  (defgeneric test-mc65-5 (x &optional y)
2726    (:method-combination mc65 "xyz")
2727    (:method (x &optional y) (list x y)))
2728  (list (test-mc65-5 'a) (test-mc65-5 'a 'b)))
2729(("xyz" "def" RESULT A NIL () (A NIL))
2730 ("xyz" "def" RESULT A NIL () (A B)))
2731
2732(progn
2733  (defgeneric test-mc65-6 (x y &optional z)
2734    (:method-combination mc65 "xyz")
2735    (:method (x y &optional z) (list x y z)))
2736  (list (test-mc65-6 'a 'b) (test-mc65-6 'a 'b 'c)))
2737(("xyz" "def" RESULT A B () (A B NIL))
2738 ("xyz" "def" RESULT A B () (A B C)))
2739
2740(progn
2741  (defgeneric test-mc65-7 (x y z &optional u)
2742    (:method-combination mc65 "xyz")
2743    (:method (x y z &optional u) (list x y z u)))
2744  (list (test-mc65-7 'a 'b 'c) (test-mc65-7 'a 'b 'c 'd)))
2745(("xyz" "def" RESULT A B () (A B C NIL))
2746 ("xyz" "def" RESULT A B () (A B C D)))
2747
2748(progn
2749  (defgeneric test-mc65-8 (x &optional y z)
2750    (:method-combination mc65 "xyz")
2751    (:method (x &optional y z) (list x y z)))
2752  (list (test-mc65-8 'a) (test-mc65-8 'a 'b) (test-mc65-8 'a 'b 'c)))
2753(("xyz" "def" RESULT A NIL () (A NIL NIL))
2754 ("xyz" "def" RESULT A NIL () (A B NIL))
2755 ("xyz" "def" RESULT A NIL () (A B C)))
2756
2757(progn
2758  (defgeneric test-mc65-9 (x y &optional z u)
2759    (:method-combination mc65 "xyz")
2760    (:method (x y &optional z u) (list x y z u)))
2761  (list (test-mc65-9 'a 'b) (test-mc65-9 'a 'b 'c) (test-mc65-9 'a 'b 'c 'd)))
2762(("xyz" "def" RESULT A B () (A B NIL NIL))
2763 ("xyz" "def" RESULT A B () (A B C NIL))
2764 ("xyz" "def" RESULT A B () (A B C D)))
2765
2766(progn
2767  (defgeneric test-mc65-10 (x y z &optional u v)
2768    (:method-combination mc65 "xyz")
2769    (:method (x y z &optional u v) (list x y z u v)))
2770  (list (test-mc65-10 'a 'b 'c) (test-mc65-10 'a 'b 'c 'd) (test-mc65-10 'a 'b 'c 'd 'e)))
2771(("xyz" "def" RESULT A B () (A B C NIL NIL))
2772 ("xyz" "def" RESULT A B () (A B C D NIL))
2773 ("xyz" "def" RESULT A B () (A B C D E)))
2774
2775(progn
2776  (defgeneric test-mc65-11 (x &optional y z u)
2777    (:method-combination mc65 "xyz")
2778    (:method (x &optional y z u) (list x y z u)))
2779  (list (test-mc65-11 'a) (test-mc65-11 'a 'b) (test-mc65-11 'a 'b 'c) (test-mc65-11 'a 'b 'c 'd)))
2780(("xyz" "def" RESULT A NIL () (A NIL NIL NIL))
2781 ("xyz" "def" RESULT A NIL () (A B NIL NIL))
2782 ("xyz" "def" RESULT A NIL () (A B C NIL))
2783 ("xyz" "def" RESULT A NIL () (A B C D)))
2784
2785(progn
2786  (defgeneric test-mc65-12 (x y &optional z u v)
2787    (:method-combination mc65 "xyz")
2788    (:method (x y &optional z u v) (list x y z u v)))
2789  (list (test-mc65-12 'a 'b) (test-mc65-12 'a 'b 'c) (test-mc65-12 'a 'b 'c 'd) (test-mc65-12 'a 'b 'c 'd 'e)))
2790(("xyz" "def" RESULT A B () (A B NIL NIL NIL))
2791 ("xyz" "def" RESULT A B () (A B C NIL NIL))
2792 ("xyz" "def" RESULT A B () (A B C D NIL))
2793 ("xyz" "def" RESULT A B () (A B C D E)))
2794
2795(progn
2796  (defgeneric test-mc65-13 (x y z &optional u v w)
2797    (:method-combination mc65 "xyz")
2798    (:method (x y z &optional u v w) (list x y z u v w)))
2799  (list (test-mc65-13 'a 'b 'c) (test-mc65-13 'a 'b 'c 'd) (test-mc65-13 'a 'b 'c 'd 'e) (test-mc65-13 'a 'b 'c 'd 'e 'f)))
2800(("xyz" "def" RESULT A B () (A B C NIL NIL NIL))
2801 ("xyz" "def" RESULT A B () (A B C D NIL NIL))
2802 ("xyz" "def" RESULT A B () (A B C D E NIL))
2803 ("xyz" "def" RESULT A B () (A B C D E F)))
2804
2805(progn
2806  (defgeneric test-mc65-14 (x &rest y)
2807    (:method-combination mc65 "xyz")
2808    (:method (x &rest y) (list* x y)))
2809  (list (test-mc65-14 'a) (test-mc65-14 'a 'b) (test-mc65-14 'a 'b 'c)))
2810(("xyz" "def" RESULT A NIL () (A))
2811 ("xyz" "def" RESULT A NIL (B) (A B))
2812 ("xyz" "def" RESULT A NIL (B C) (A B C)))
2813
2814(progn
2815  (defgeneric test-mc65-15 (x y &rest z)
2816    (:method-combination mc65 "xyz")
2817    (:method (x y &rest z) (list* x y z)))
2818  (list (test-mc65-15 'a 'b) (test-mc65-15 'a 'b 'c) (test-mc65-15 'a 'b 'c 'd)))
2819(("xyz" "def" RESULT A B () (A B))
2820 ("xyz" "def" RESULT A B (C) (A B C))
2821 ("xyz" "def" RESULT A B (C D) (A B C D)))
2822
2823(progn
2824  (defgeneric test-mc65-16 (x y z &rest u)
2825    (:method-combination mc65 "xyz")
2826    (:method (x y z &rest u) (list* x y z u)))
2827  (list (test-mc65-16 'a 'b 'c) (test-mc65-16 'a 'b 'c 'd) (test-mc65-16 'a 'b 'c 'd 'e)))
2828(("xyz" "def" RESULT A B () (A B C))
2829 ("xyz" "def" RESULT A B (D) (A B C D))
2830 ("xyz" "def" RESULT A B (D E) (A B C D E)))
2831
2832(progn
2833  (defgeneric test-mc65-17 (x &optional y &rest z)
2834    (:method-combination mc65 "xyz")
2835    (:method (x &optional y &rest z) (list* x y z)))
2836  (list (test-mc65-17 'a) (test-mc65-17 'a 'b) (test-mc65-17 'a 'b 'c) (test-mc65-17 'a 'b 'c 'd)))
2837(("xyz" "def" RESULT A NIL () (A NIL))
2838 ("xyz" "def" RESULT A NIL () (A B))
2839 ("xyz" "def" RESULT A NIL (C) (A B C))
2840 ("xyz" "def" RESULT A NIL (C D) (A B C D)))
2841
2842(progn
2843  (defgeneric test-mc65-18 (x &optional y z &rest u)
2844    (:method-combination mc65 "xyz")
2845    (:method (x &optional y z &rest u) (list* x y z u)))
2846  (list (test-mc65-18 'a) (test-mc65-18 'a 'b) (test-mc65-18 'a 'b 'c) (test-mc65-18 'a 'b 'c 'd) (test-mc65-18 'a 'b 'c 'd 'e)))
2847(("xyz" "def" RESULT A NIL () (A NIL NIL))
2848 ("xyz" "def" RESULT A NIL () (A B NIL))
2849 ("xyz" "def" RESULT A NIL () (A B C))
2850 ("xyz" "def" RESULT A NIL (D) (A B C D))
2851 ("xyz" "def" RESULT A NIL (D E) (A B C D E)))
2852
2853(progn
2854  (defgeneric test-mc65-19 (x &optional y z u &rest v)
2855    (:method-combination mc65 "xyz")
2856    (:method (x &optional y z u &rest v) (list* x y z u v)))
2857  (list (test-mc65-19 'a) (test-mc65-19 'a 'b) (test-mc65-19 'a 'b 'c) (test-mc65-19 'a 'b 'c 'd) (test-mc65-19 'a 'b 'c 'd 'e) (test-mc65-19 'a 'b 'c 'd 'e 'f)))
2858(("xyz" "def" RESULT A NIL () (A NIL NIL NIL))
2859 ("xyz" "def" RESULT A NIL () (A B NIL NIL))
2860 ("xyz" "def" RESULT A NIL () (A B C NIL))
2861 ("xyz" "def" RESULT A NIL () (A B C D))
2862 ("xyz" "def" RESULT A NIL (E) (A B C D E))
2863 ("xyz" "def" RESULT A NIL (E F) (A B C D E F)))
2864
2865; Check :arguments with optional and rest arguments.
2866(define-method-combination mc66 (opt1 &optional (opt2 "def")) ((all *))
2867  (:arguments &optional (o1 'def1) (o2 'def2) &rest r)
2868  `(LIST ',opt1 ',opt2 'RESULT ,o1 ,o2 ,r (CALL-METHOD ,(first all))))
2869MC66
2870
2871(progn
2872  (defgeneric test-mc66-1 ()
2873    (:method-combination mc66 "xyz")
2874    (:method () '()))
2875  (test-mc66-1))
2876("xyz" "def" RESULT DEF1 DEF2 () ())
2877
2878(progn
2879  (defgeneric test-mc66-2 (x)
2880    (:method-combination mc66 "xyz")
2881    (:method (x) (list x)))
2882  (test-mc66-2 'a))
2883("xyz" "def" RESULT DEF1 DEF2 () (A))
2884
2885(progn
2886  (defgeneric test-mc66-3 (x y)
2887    (:method-combination mc66 "xyz")
2888    (:method (x y) (list x y)))
2889  (test-mc66-3 'a 'b))
2890("xyz" "def" RESULT DEF1 DEF2 () (A B))
2891
2892(progn
2893  (defgeneric test-mc66-4 (x y z)
2894    (:method-combination mc66 "xyz")
2895    (:method (x y z) (list x y z)))
2896  (test-mc66-4 'a 'b 'c))
2897("xyz" "def" RESULT DEF1 DEF2 () (A B C))
2898
2899(progn
2900  (defgeneric test-mc66-5 (x &optional y)
2901    (:method-combination mc66 "xyz")
2902    (:method (x &optional y) (list x y)))
2903  (list (test-mc66-5 'a) (test-mc66-5 'a 'b)))
2904(("xyz" "def" RESULT DEF1 DEF2 () (A NIL))
2905 ("xyz" "def" RESULT B DEF2 () (A B)))
2906
2907(progn
2908  (defgeneric test-mc66-6 (x y &optional z)
2909    (:method-combination mc66 "xyz")
2910    (:method (x y &optional z) (list x y z)))
2911  (list (test-mc66-6 'a 'b) (test-mc66-6 'a 'b 'c)))
2912(("xyz" "def" RESULT DEF1 DEF2 () (A B NIL))
2913 ("xyz" "def" RESULT C DEF2 () (A B C)))
2914
2915(progn
2916  (defgeneric test-mc66-7 (x y z &optional u)
2917    (:method-combination mc66 "xyz")
2918    (:method (x y z &optional u) (list x y z u)))
2919  (list (test-mc66-7 'a 'b 'c) (test-mc66-7 'a 'b 'c 'd)))
2920(("xyz" "def" RESULT DEF1 DEF2 () (A B C NIL))
2921 ("xyz" "def" RESULT D DEF2 () (A B C D)))
2922
2923(progn
2924  (defgeneric test-mc66-8 (x &optional y z)
2925    (:method-combination mc66 "xyz")
2926    (:method (x &optional y z) (list x y z)))
2927  (list (test-mc66-8 'a) (test-mc66-8 'a 'b) (test-mc66-8 'a 'b 'c)))
2928(("xyz" "def" RESULT DEF1 DEF2 () (A NIL NIL))
2929 ("xyz" "def" RESULT B DEF2 () (A B NIL))
2930 ("xyz" "def" RESULT B C () (A B C)))
2931
2932(progn
2933  (defgeneric test-mc66-9 (x y &optional z u)
2934    (:method-combination mc66 "xyz")
2935    (:method (x y &optional z u) (list x y z u)))
2936  (list (test-mc66-9 'a 'b) (test-mc66-9 'a 'b 'c) (test-mc66-9 'a 'b 'c 'd)))
2937(("xyz" "def" RESULT DEF1 DEF2 () (A B NIL NIL))
2938 ("xyz" "def" RESULT C DEF2 () (A B C NIL))
2939 ("xyz" "def" RESULT C D () (A B C D)))
2940
2941(progn
2942  (defgeneric test-mc66-10 (x y z &optional u v)
2943    (:method-combination mc66 "xyz")
2944    (:method (x y z &optional u v) (list x y z u v)))
2945  (list (test-mc66-10 'a 'b 'c) (test-mc66-10 'a 'b 'c 'd) (test-mc66-10 'a 'b 'c 'd 'e)))
2946(("xyz" "def" RESULT DEF1 DEF2 () (A B C NIL NIL))
2947 ("xyz" "def" RESULT D DEF2 () (A B C D NIL))
2948 ("xyz" "def" RESULT D E () (A B C D E)))
2949
2950(progn
2951  (defgeneric test-mc66-11 (x &optional y z u)
2952    (:method-combination mc66 "xyz")
2953    (:method (x &optional y z u) (list x y z u)))
2954  (list (test-mc66-11 'a) (test-mc66-11 'a 'b) (test-mc66-11 'a 'b 'c) (test-mc66-11 'a 'b 'c 'd)))
2955(("xyz" "def" RESULT DEF1 DEF2 () (A NIL NIL NIL))
2956 ("xyz" "def" RESULT B DEF2 () (A B NIL NIL))
2957 ("xyz" "def" RESULT B C () (A B C NIL))
2958 ("xyz" "def" RESULT B C () (A B C D)))
2959
2960(progn
2961  (defgeneric test-mc66-12 (x y &optional z u v)
2962    (:method-combination mc66 "xyz")
2963    (:method (x y &optional z u v) (list x y z u v)))
2964  (list (test-mc66-12 'a 'b) (test-mc66-12 'a 'b 'c) (test-mc66-12 'a 'b 'c 'd) (test-mc66-12 'a 'b 'c 'd 'e)))
2965(("xyz" "def" RESULT DEF1 DEF2 () (A B NIL NIL NIL))
2966 ("xyz" "def" RESULT C DEF2 () (A B C NIL NIL))
2967 ("xyz" "def" RESULT C D () (A B C D NIL))
2968 ("xyz" "def" RESULT C D () (A B C D E)))
2969
2970(progn
2971  (defgeneric test-mc66-13 (x y z &optional u v w)
2972    (:method-combination mc66 "xyz")
2973    (:method (x y z &optional u v w) (list x y z u v w)))
2974  (list (test-mc66-13 'a 'b 'c) (test-mc66-13 'a 'b 'c 'd) (test-mc66-13 'a 'b 'c 'd 'e) (test-mc66-13 'a 'b 'c 'd 'e 'f)))
2975(("xyz" "def" RESULT DEF1 DEF2 () (A B C NIL NIL NIL))
2976 ("xyz" "def" RESULT D DEF2 () (A B C D NIL NIL))
2977 ("xyz" "def" RESULT D E () (A B C D E NIL))
2978 ("xyz" "def" RESULT D E () (A B C D E F)))
2979
2980(progn
2981  (defgeneric test-mc66-14 (x &rest y)
2982    (:method-combination mc66 "xyz")
2983    (:method (x &rest y) (list* x y)))
2984  (list (test-mc66-14 'a) (test-mc66-14 'a 'b) (test-mc66-14 'a 'b 'c)))
2985(("xyz" "def" RESULT DEF1 DEF2 () (A))
2986 ("xyz" "def" RESULT DEF1 DEF2 (B) (A B))
2987 ("xyz" "def" RESULT DEF1 DEF2 (B C) (A B C)))
2988
2989(progn
2990  (defgeneric test-mc66-15 (x y &rest z)
2991    (:method-combination mc66 "xyz")
2992    (:method (x y &rest z) (list* x y z)))
2993  (list (test-mc66-15 'a 'b) (test-mc66-15 'a 'b 'c) (test-mc66-15 'a 'b 'c 'd)))
2994(("xyz" "def" RESULT DEF1 DEF2 () (A B))
2995 ("xyz" "def" RESULT DEF1 DEF2 (C) (A B C))
2996 ("xyz" "def" RESULT DEF1 DEF2 (C D) (A B C D)))
2997
2998(progn
2999  (defgeneric test-mc66-16 (x y z &rest u)
3000    (:method-combination mc66 "xyz")
3001    (:method (x y z &rest u) (list* x y z u)))
3002  (list (test-mc66-16 'a 'b 'c) (test-mc66-16 'a 'b 'c 'd) (test-mc66-16 'a 'b 'c 'd 'e)))
3003(("xyz" "def" RESULT DEF1 DEF2 () (A B C))
3004 ("xyz" "def" RESULT DEF1 DEF2 (D) (A B C D))
3005 ("xyz" "def" RESULT DEF1 DEF2 (D E) (A B C D E)))
3006
3007(progn
3008  (defgeneric test-mc66-17 (x &optional y &rest z)
3009    (:method-combination mc66 "xyz")
3010    (:method (x &optional y &rest z) (list* x y z)))
3011  (list (test-mc66-17 'a) (test-mc66-17 'a 'b) (test-mc66-17 'a 'b 'c) (test-mc66-17 'a 'b 'c 'd)))
3012(("xyz" "def" RESULT DEF1 DEF2 () (A NIL))
3013 ("xyz" "def" RESULT B DEF2 () (A B))
3014 ("xyz" "def" RESULT B DEF2 (C) (A B C))
3015 ("xyz" "def" RESULT B DEF2 (C D) (A B C D)))
3016
3017(progn
3018  (defgeneric test-mc66-18 (x &optional y z &rest u)
3019    (:method-combination mc66 "xyz")
3020    (:method (x &optional y z &rest u) (list* x y z u)))
3021  (list (test-mc66-18 'a) (test-mc66-18 'a 'b) (test-mc66-18 'a 'b 'c) (test-mc66-18 'a 'b 'c 'd) (test-mc66-18 'a 'b 'c 'd 'e)))
3022(("xyz" "def" RESULT DEF1 DEF2 () (A NIL NIL))
3023 ("xyz" "def" RESULT B DEF2 () (A B NIL))
3024 ("xyz" "def" RESULT B C () (A B C))
3025 ("xyz" "def" RESULT B C (D) (A B C D))
3026 ("xyz" "def" RESULT B C (D E) (A B C D E)))
3027
3028(progn
3029  (defgeneric test-mc66-19 (x &optional y z u &rest v)
3030    (:method-combination mc66 "xyz")
3031    (:method (x &optional y z u &rest v) (list* x y z u v)))
3032  (list (test-mc66-19 'a) (test-mc66-19 'a 'b) (test-mc66-19 'a 'b 'c) (test-mc66-19 'a 'b 'c 'd) (test-mc66-19 'a 'b 'c 'd 'e) (test-mc66-19 'a 'b 'c 'd 'e 'f)))
3033(("xyz" "def" RESULT DEF1 DEF2 () (A NIL NIL NIL))
3034 ("xyz" "def" RESULT B DEF2 () (A B NIL NIL))
3035 ("xyz" "def" RESULT B C () (A B C NIL))
3036 ("xyz" "def" RESULT B C () (A B C D))
3037 ("xyz" "def" RESULT B C (E) (A B C D E))
3038 ("xyz" "def" RESULT B C (E F) (A B C D E F)))
3039
3040; Check :arguments with required, optional and rest arguments.
3041(define-method-combination mc67 (opt1 &optional (opt2 "def")) ((all *))
3042  (:arguments a1 a2 &optional (o1 'def1) (o2 'def2) &rest r)
3043  `(LIST ',opt1 ',opt2 'RESULT ,a1 ,a2 ,o1 ,o2 ,r (CALL-METHOD ,(first all))))
3044MC67
3045
3046(progn
3047  (defgeneric test-mc67-1 ()
3048    (:method-combination mc67 "xyz")
3049    (:method () '()))
3050  (test-mc67-1))
3051("xyz" "def" RESULT NIL NIL DEF1 DEF2 () ())
3052
3053(progn
3054  (defgeneric test-mc67-2 (x)
3055    (:method-combination mc67 "xyz")
3056    (:method (x) (list x)))
3057  (test-mc67-2 'a))
3058("xyz" "def" RESULT A NIL DEF1 DEF2 () (A))
3059
3060(progn
3061  (defgeneric test-mc67-3 (x y)
3062    (:method-combination mc67 "xyz")
3063    (:method (x y) (list x y)))
3064  (test-mc67-3 'a 'b))
3065("xyz" "def" RESULT A B DEF1 DEF2 () (A B))
3066
3067(progn
3068  (defgeneric test-mc67-4 (x y z)
3069    (:method-combination mc67 "xyz")
3070    (:method (x y z) (list x y z)))
3071  (test-mc67-4 'a 'b 'c))
3072("xyz" "def" RESULT A B DEF1 DEF2 () (A B C))
3073
3074(progn
3075  (defgeneric test-mc67-5 (x &optional y)
3076    (:method-combination mc67 "xyz")
3077    (:method (x &optional y) (list x y)))
3078  (list (test-mc67-5 'a) (test-mc67-5 'a 'b)))
3079(("xyz" "def" RESULT A NIL DEF1 DEF2 () (A NIL))
3080 ("xyz" "def" RESULT A NIL B DEF2 () (A B)))
3081
3082(progn
3083  (defgeneric test-mc67-6 (x y &optional z)
3084    (:method-combination mc67 "xyz")
3085    (:method (x y &optional z) (list x y z)))
3086  (list (test-mc67-6 'a 'b) (test-mc67-6 'a 'b 'c)))
3087(("xyz" "def" RESULT A B DEF1 DEF2 () (A B NIL))
3088 ("xyz" "def" RESULT A B C DEF2 () (A B C)))
3089
3090(progn
3091  (defgeneric test-mc67-7 (x y z &optional u)
3092    (:method-combination mc67 "xyz")
3093    (:method (x y z &optional u) (list x y z u)))
3094  (list (test-mc67-7 'a 'b 'c) (test-mc67-7 'a 'b 'c 'd)))
3095(("xyz" "def" RESULT A B DEF1 DEF2 () (A B C NIL))
3096 ("xyz" "def" RESULT A B D DEF2 () (A B C D)))
3097
3098(progn
3099  (defgeneric test-mc67-8 (x &optional y z)
3100    (:method-combination mc67 "xyz")
3101    (:method (x &optional y z) (list x y z)))
3102  (list (test-mc67-8 'a) (test-mc67-8 'a 'b) (test-mc67-8 'a 'b 'c)))
3103(("xyz" "def" RESULT A NIL DEF1 DEF2 () (A NIL NIL))
3104 ("xyz" "def" RESULT A NIL B DEF2 () (A B NIL))
3105 ("xyz" "def" RESULT A NIL B C () (A B C)))
3106
3107(progn
3108  (defgeneric test-mc67-9 (x y &optional z u)
3109    (:method-combination mc67 "xyz")
3110    (:method (x y &optional z u) (list x y z u)))
3111  (list (test-mc67-9 'a 'b) (test-mc67-9 'a 'b 'c) (test-mc67-9 'a 'b 'c 'd)))
3112(("xyz" "def" RESULT A B DEF1 DEF2 () (A B NIL NIL))
3113 ("xyz" "def" RESULT A B C DEF2 () (A B C NIL))
3114 ("xyz" "def" RESULT A B C D () (A B C D)))
3115
3116(progn
3117  (defgeneric test-mc67-10 (x y z &optional u v)
3118    (:method-combination mc67 "xyz")
3119    (:method (x y z &optional u v) (list x y z u v)))
3120  (list (test-mc67-10 'a 'b 'c) (test-mc67-10 'a 'b 'c 'd) (test-mc67-10 'a 'b 'c 'd 'e)))
3121(("xyz" "def" RESULT A B DEF1 DEF2 () (A B C NIL NIL))
3122 ("xyz" "def" RESULT A B D DEF2 () (A B C D NIL))
3123 ("xyz" "def" RESULT A B D E () (A B C D E)))
3124
3125(progn
3126  (defgeneric test-mc67-11 (x &optional y z u)
3127    (:method-combination mc67 "xyz")
3128    (:method (x &optional y z u) (list x y z u)))
3129  (list (test-mc67-11 'a) (test-mc67-11 'a 'b) (test-mc67-11 'a 'b 'c) (test-mc67-11 'a 'b 'c 'd)))
3130(("xyz" "def" RESULT A NIL DEF1 DEF2 () (A NIL NIL NIL))
3131 ("xyz" "def" RESULT A NIL B DEF2 () (A B NIL NIL))
3132 ("xyz" "def" RESULT A NIL B C () (A B C NIL))
3133 ("xyz" "def" RESULT A NIL B C () (A B C D)))
3134
3135(progn
3136  (defgeneric test-mc67-12 (x y &optional z u v)
3137    (:method-combination mc67 "xyz")
3138    (:method (x y &optional z u v) (list x y z u v)))
3139  (list (test-mc67-12 'a 'b) (test-mc67-12 'a 'b 'c) (test-mc67-12 'a 'b 'c 'd) (test-mc67-12 'a 'b 'c 'd 'e)))
3140(("xyz" "def" RESULT A B DEF1 DEF2 () (A B NIL NIL NIL))
3141 ("xyz" "def" RESULT A B C DEF2 () (A B C NIL NIL))
3142 ("xyz" "def" RESULT A B C D () (A B C D NIL))
3143 ("xyz" "def" RESULT A B C D () (A B C D E)))
3144
3145(progn
3146  (defgeneric test-mc67-13 (x y z &optional u v w)
3147    (:method-combination mc67 "xyz")
3148    (:method (x y z &optional u v w) (list x y z u v w)))
3149  (list (test-mc67-13 'a 'b 'c) (test-mc67-13 'a 'b 'c 'd) (test-mc67-13 'a 'b 'c 'd 'e) (test-mc67-13 'a 'b 'c 'd 'e 'f)))
3150(("xyz" "def" RESULT A B DEF1 DEF2 () (A B C NIL NIL NIL))
3151 ("xyz" "def" RESULT A B D DEF2 () (A B C D NIL NIL))
3152 ("xyz" "def" RESULT A B D E () (A B C D E NIL))
3153 ("xyz" "def" RESULT A B D E () (A B C D E F)))
3154
3155(progn
3156  (defgeneric test-mc67-14 (x &rest y)
3157    (:method-combination mc67 "xyz")
3158    (:method (x &rest y) (list* x y)))
3159  (list (test-mc67-14 'a) (test-mc67-14 'a 'b) (test-mc67-14 'a 'b 'c)))
3160(("xyz" "def" RESULT A NIL DEF1 DEF2 () (A))
3161 ("xyz" "def" RESULT A NIL DEF1 DEF2 (B) (A B))
3162 ("xyz" "def" RESULT A NIL DEF1 DEF2 (B C) (A B C)))
3163
3164(progn
3165  (defgeneric test-mc67-15 (x y &rest z)
3166    (:method-combination mc67 "xyz")
3167    (:method (x y &rest z) (list* x y z)))
3168  (list (test-mc67-15 'a 'b) (test-mc67-15 'a 'b 'c) (test-mc67-15 'a 'b 'c 'd)))
3169(("xyz" "def" RESULT A B DEF1 DEF2 () (A B))
3170 ("xyz" "def" RESULT A B DEF1 DEF2 (C) (A B C))
3171 ("xyz" "def" RESULT A B DEF1 DEF2 (C D) (A B C D)))
3172
3173(progn
3174  (defgeneric test-mc67-16 (x y z &rest u)
3175    (:method-combination mc67 "xyz")
3176    (:method (x y z &rest u) (list* x y z u)))
3177  (list (test-mc67-16 'a 'b 'c) (test-mc67-16 'a 'b 'c 'd) (test-mc67-16 'a 'b 'c 'd 'e)))
3178(("xyz" "def" RESULT A B DEF1 DEF2 () (A B C))
3179 ("xyz" "def" RESULT A B DEF1 DEF2 (D) (A B C D))
3180 ("xyz" "def" RESULT A B DEF1 DEF2 (D E) (A B C D E)))
3181
3182(progn
3183  (defgeneric test-mc67-17 (x &optional y &rest z)
3184    (:method-combination mc67 "xyz")
3185    (:method (x &optional y &rest z) (list* x y z)))
3186  (list (test-mc67-17 'a) (test-mc67-17 'a 'b) (test-mc67-17 'a 'b 'c) (test-mc67-17 'a 'b 'c 'd)))
3187(("xyz" "def" RESULT A NIL DEF1 DEF2 () (A NIL))
3188 ("xyz" "def" RESULT A NIL B DEF2 () (A B))
3189 ("xyz" "def" RESULT A NIL B DEF2 (C) (A B C))
3190 ("xyz" "def" RESULT A NIL B DEF2 (C D) (A B C D)))
3191
3192(progn
3193  (defgeneric test-mc67-18 (x &optional y z &rest u)
3194    (:method-combination mc67 "xyz")
3195    (:method (x &optional y z &rest u) (list* x y z u)))
3196  (list (test-mc67-18 'a) (test-mc67-18 'a 'b) (test-mc67-18 'a 'b 'c) (test-mc67-18 'a 'b 'c 'd) (test-mc67-18 'a 'b 'c 'd 'e)))
3197(("xyz" "def" RESULT A NIL DEF1 DEF2 () (A NIL NIL))
3198 ("xyz" "def" RESULT A NIL B DEF2 () (A B NIL))
3199 ("xyz" "def" RESULT A NIL B C () (A B C))
3200 ("xyz" "def" RESULT A NIL B C (D) (A B C D))
3201 ("xyz" "def" RESULT A NIL B C (D E) (A B C D E)))
3202
3203(progn
3204  (defgeneric test-mc67-19 (x &optional y z u &rest v)
3205    (:method-combination mc67 "xyz")
3206    (:method (x &optional y z u &rest v) (list* x y z u v)))
3207  (list (test-mc67-19 'a) (test-mc67-19 'a 'b) (test-mc67-19 'a 'b 'c) (test-mc67-19 'a 'b 'c 'd) (test-mc67-19 'a 'b 'c 'd 'e) (test-mc67-19 'a 'b 'c 'd 'e 'f)))
3208(("xyz" "def" RESULT A NIL DEF1 DEF2 () (A NIL NIL NIL))
3209 ("xyz" "def" RESULT A NIL B DEF2 () (A B NIL NIL))
3210 ("xyz" "def" RESULT A NIL B C () (A B C NIL))
3211 ("xyz" "def" RESULT A NIL B C () (A B C D))
3212 ("xyz" "def" RESULT A NIL B C (E) (A B C D E))
3213 ("xyz" "def" RESULT A NIL B C (E F) (A B C D E F)))
3214
3215; Check :arguments with required, optional and key arguments.
3216(define-method-combination mc68 (opt1 &optional (opt2 "def")) ((all *))
3217  (:arguments a1 a2 &optional (o1 'def1) (o2 'def2) &key (test 'EQ) (test-not 'NEQ))
3218  `(LIST ',opt1 ',opt2 'RESULT ,a1 ,a2 ,o1 ,o2 ,test ,test-not (CALL-METHOD ,(first all))))
3219MC68
3220
3221(progn
3222  (defgeneric test-mc68-1 (x &optional y)
3223    (:method-combination mc68 "xyz")
3224    (:method (x &optional y) (list x y)))
3225  (list (test-mc68-1 'a) (test-mc68-1 'a 'b)))
3226(("xyz" "def" RESULT A NIL DEF1 DEF2 EQ NEQ (A NIL))
3227 ("xyz" "def" RESULT A NIL B DEF2 EQ NEQ (A B)))
3228
3229(progn
3230  (defgeneric test-mc68-2 (x y z &optional u v w)
3231    (:method-combination mc68 "xyz")
3232    (:method (x y z &optional u v w) (list x y z u v w)))
3233  (list (test-mc68-2 'a 'b 'c) (test-mc68-2 'a 'b 'c 'd) (test-mc68-2 'a 'b 'c 'd 'e) (test-mc68-2 'a 'b 'c 'd 'e 'f)))
3234(("xyz" "def" RESULT A B DEF1 DEF2 EQ NEQ (A B C NIL NIL NIL))
3235 ("xyz" "def" RESULT A B D DEF2 EQ NEQ (A B C D NIL NIL))
3236 ("xyz" "def" RESULT A B D E EQ NEQ (A B C D E NIL))
3237 ("xyz" "def" RESULT A B D E EQ NEQ (A B C D E F)))
3238
3239(progn
3240  (defgeneric test-mc68-3 (x &rest y)
3241    (:method-combination mc68 "xyz")
3242    (:method (x &rest y) (list* x y)))
3243  (list (test-mc68-3 'a) (test-mc68-3 'a 'b 'c)
3244        (test-mc68-3 'a :test-not 'nequal :test 'eql :test-not 'nequalp)))
3245(("xyz" "def" RESULT A NIL DEF1 DEF2 EQ NEQ (A))
3246 ("xyz" "def" RESULT A NIL DEF1 DEF2 EQ NEQ (A B C))
3247 ("xyz" "def" RESULT A NIL DEF1 DEF2 EQL NEQUAL (A :TEST-NOT NEQUAL :TEST EQL :TEST-NOT NEQUALP)))
3248
3249(progn
3250  (defgeneric test-mc68-4 (x &rest y)
3251    (:method-combination mc68 "xyz")
3252    (:method (x &rest y) (list* x y)))
3253  (test-mc68-4 'a 'b))
3254ERROR
3255
3256(progn
3257  (defgeneric test-mc68-5 (x y z &rest u)
3258    (:method-combination mc68 "xyz")
3259    (:method (x y z &rest u) (list* x y z u)))
3260  (list (test-mc68-5 'a :test 'eq) (test-mc68-5 'a :test 'eq 'd 'e)
3261        (test-mc68-5 'a :test 'eq :test-not 'nequal :test 'eql :test-not 'nequalp)))
3262(("xyz" "def" RESULT A :TEST DEF1 DEF2 EQ NEQ (A :TEST EQ))
3263 ("xyz" "def" RESULT A :TEST DEF1 DEF2 EQ NEQ (A :TEST EQ D E))
3264 ("xyz" "def" RESULT A :TEST DEF1 DEF2 EQL NEQUAL (A :TEST EQ :TEST-NOT NEQUAL :TEST EQL :TEST-NOT NEQUALP)))
3265
3266(progn
3267  (defgeneric test-mc68-6 (x &optional y z u &rest v)
3268    (:method-combination mc68 "xyz")
3269    (:method (x &optional y z u &rest v) (list* x y z u v)))
3270  (list (test-mc68-6 'a) (test-mc68-6 'a 'b 'c)
3271        (test-mc68-6 'a :test 'eq 'd :test-not 'nequal :test 'eql :test-not 'nequalp)))
3272(("xyz" "def" RESULT A NIL DEF1 DEF2 EQ NEQ (A NIL NIL NIL))
3273 ("xyz" "def" RESULT A NIL B C EQ NEQ (A B C NIL))
3274 ("xyz" "def" RESULT A NIL :TEST EQ EQL NEQUAL (A :TEST EQ D :TEST-NOT NEQUAL :TEST EQL :TEST-NOT NEQUALP)))
3275
3276; Check :arguments with just &whole.
3277(define-method-combination mc69 (opt1 &optional (opt2 "def")) ((all *))
3278  (:arguments &whole whole)
3279  `(LIST ',opt1 ',opt2 'RESULT ,whole (CALL-METHOD ,(first all))))
3280MC69
3281
3282(progn
3283  (defgeneric test-mc69-1 ()
3284    (:method-combination mc69 "xyz")
3285    (:method () '()))
3286  (test-mc69-1))
3287("xyz" "def" RESULT () ())
3288
3289(progn
3290  (defgeneric test-mc69-2 (x)
3291    (:method-combination mc69 "xyz")
3292    (:method (x) (list x)))
3293  (test-mc69-2 'a))
3294("xyz" "def" RESULT (A) (A))
3295
3296(progn
3297  (defgeneric test-mc69-3 (x y)
3298    (:method-combination mc69 "xyz")
3299    (:method (x y) (list x y)))
3300  (test-mc69-3 'a 'b))
3301("xyz" "def" RESULT (A B) (A B))
3302
3303(progn
3304  (defgeneric test-mc69-4 (x y z)
3305    (:method-combination mc69 "xyz")
3306    (:method (x y z) (list x y z)))
3307  (test-mc69-4 'a 'b 'c))
3308("xyz" "def" RESULT (A B C) (A B C))
3309
3310(progn
3311  (defgeneric test-mc69-5 (x &optional y)
3312    (:method-combination mc69 "xyz")
3313    (:method (x &optional y) (list x y)))
3314  (list (test-mc69-5 'a) (test-mc69-5 'a 'b)))
3315(("xyz" "def" RESULT (A) (A NIL))
3316 ("xyz" "def" RESULT (A B) (A B)))
3317
3318(progn
3319  (defgeneric test-mc69-6 (x y &optional z)
3320    (:method-combination mc69 "xyz")
3321    (:method (x y &optional z) (list x y z)))
3322  (list (test-mc69-6 'a 'b) (test-mc69-6 'a 'b 'c)))
3323(("xyz" "def" RESULT (A B) (A B NIL))
3324 ("xyz" "def" RESULT (A B C) (A B C)))
3325
3326(progn
3327  (defgeneric test-mc69-7 (x y z &optional u)
3328    (:method-combination mc69 "xyz")
3329    (:method (x y z &optional u) (list x y z u)))
3330  (list (test-mc69-7 'a 'b 'c) (test-mc69-7 'a 'b 'c 'd)))
3331(("xyz" "def" RESULT (A B C) (A B C NIL))
3332 ("xyz" "def" RESULT (A B C D) (A B C D)))
3333
3334(progn
3335  (defgeneric test-mc69-8 (x &optional y z)
3336    (:method-combination mc69 "xyz")
3337    (:method (x &optional y z) (list x y z)))
3338  (list (test-mc69-8 'a) (test-mc69-8 'a 'b) (test-mc69-8 'a 'b 'c)))
3339(("xyz" "def" RESULT (A) (A NIL NIL))
3340 ("xyz" "def" RESULT (A B) (A B NIL))
3341 ("xyz" "def" RESULT (A B C) (A B C)))
3342
3343(progn
3344  (defgeneric test-mc69-9 (x y &optional z u)
3345    (:method-combination mc69 "xyz")
3346    (:method (x y &optional z u) (list x y z u)))
3347  (list (test-mc69-9 'a 'b) (test-mc69-9 'a 'b 'c) (test-mc69-9 'a 'b 'c 'd)))
3348(("xyz" "def" RESULT (A B) (A B NIL NIL))
3349 ("xyz" "def" RESULT (A B C) (A B C NIL))
3350 ("xyz" "def" RESULT (A B C D) (A B C D)))
3351
3352(progn
3353  (defgeneric test-mc69-10 (x y z &optional u v)
3354    (:method-combination mc69 "xyz")
3355    (:method (x y z &optional u v) (list x y z u v)))
3356  (list (test-mc69-10 'a 'b 'c) (test-mc69-10 'a 'b 'c 'd) (test-mc69-10 'a 'b 'c 'd 'e)))
3357(("xyz" "def" RESULT (A B C) (A B C NIL NIL))
3358 ("xyz" "def" RESULT (A B C D) (A B C D NIL))
3359 ("xyz" "def" RESULT (A B C D E) (A B C D E)))
3360
3361(progn
3362  (defgeneric test-mc69-11 (x &optional y z u)
3363    (:method-combination mc69 "xyz")
3364    (:method (x &optional y z u) (list x y z u)))
3365  (list (test-mc69-11 'a) (test-mc69-11 'a 'b) (test-mc69-11 'a 'b 'c) (test-mc69-11 'a 'b 'c 'd)))
3366(("xyz" "def" RESULT (A) (A NIL NIL NIL))
3367 ("xyz" "def" RESULT (A B) (A B NIL NIL))
3368 ("xyz" "def" RESULT (A B C) (A B C NIL))
3369 ("xyz" "def" RESULT (A B C D) (A B C D)))
3370
3371(progn
3372  (defgeneric test-mc69-12 (x y &optional z u v)
3373    (:method-combination mc69 "xyz")
3374    (:method (x y &optional z u v) (list x y z u v)))
3375  (list (test-mc69-12 'a 'b) (test-mc69-12 'a 'b 'c) (test-mc69-12 'a 'b 'c 'd) (test-mc69-12 'a 'b 'c 'd 'e)))
3376(("xyz" "def" RESULT (A B) (A B NIL NIL NIL))
3377 ("xyz" "def" RESULT (A B C) (A B C NIL NIL))
3378 ("xyz" "def" RESULT (A B C D) (A B C D NIL))
3379 ("xyz" "def" RESULT (A B C D E) (A B C D E)))
3380
3381(progn
3382  (defgeneric test-mc69-13 (x y z &optional u v w)
3383    (:method-combination mc69 "xyz")
3384    (:method (x y z &optional u v w) (list x y z u v w)))
3385  (list (test-mc69-13 'a 'b 'c) (test-mc69-13 'a 'b 'c 'd) (test-mc69-13 'a 'b 'c 'd 'e) (test-mc69-13 'a 'b 'c 'd 'e 'f)))
3386(("xyz" "def" RESULT (A B C) (A B C NIL NIL NIL))
3387 ("xyz" "def" RESULT (A B C D) (A B C D NIL NIL))
3388 ("xyz" "def" RESULT (A B C D E) (A B C D E NIL))
3389 ("xyz" "def" RESULT (A B C D E F) (A B C D E F)))
3390
3391(progn
3392  (defgeneric test-mc69-14 (x &rest y)
3393    (:method-combination mc69 "xyz")
3394    (:method (x &rest y) (list* x y)))
3395  (list (test-mc69-14 'a) (test-mc69-14 'a 'b) (test-mc69-14 'a 'b 'c)))
3396(("xyz" "def" RESULT (A) (A))
3397 ("xyz" "def" RESULT (A B) (A B))
3398 ("xyz" "def" RESULT (A B C) (A B C)))
3399
3400(progn
3401  (defgeneric test-mc69-15 (x y &rest z)
3402    (:method-combination mc69 "xyz")
3403    (:method (x y &rest z) (list* x y z)))
3404  (list (test-mc69-15 'a 'b) (test-mc69-15 'a 'b 'c) (test-mc69-15 'a 'b 'c 'd)))
3405(("xyz" "def" RESULT (A B) (A B))
3406 ("xyz" "def" RESULT (A B C) (A B C))
3407 ("xyz" "def" RESULT (A B C D) (A B C D)))
3408
3409(progn
3410  (defgeneric test-mc69-16 (x y z &rest u)
3411    (:method-combination mc69 "xyz")
3412    (:method (x y z &rest u) (list* x y z u)))
3413  (list (test-mc69-16 'a 'b 'c) (test-mc69-16 'a 'b 'c 'd) (test-mc69-16 'a 'b 'c 'd 'e)))
3414(("xyz" "def" RESULT (A B C) (A B C))
3415 ("xyz" "def" RESULT (A B C D) (A B C D))
3416 ("xyz" "def" RESULT (A B C D E) (A B C D E)))
3417
3418(progn
3419  (defgeneric test-mc69-17 (x &optional y &rest z)
3420    (:method-combination mc69 "xyz")
3421    (:method (x &optional y &rest z) (list* x y z)))
3422  (list (test-mc69-17 'a) (test-mc69-17 'a 'b) (test-mc69-17 'a 'b 'c) (test-mc69-17 'a 'b 'c 'd)))
3423(("xyz" "def" RESULT (A) (A NIL))
3424 ("xyz" "def" RESULT (A B) (A B))
3425 ("xyz" "def" RESULT (A B C) (A B C))
3426 ("xyz" "def" RESULT (A B C D) (A B C D)))
3427
3428(progn
3429  (defgeneric test-mc69-18 (x &optional y z &rest u)
3430    (:method-combination mc69 "xyz")
3431    (:method (x &optional y z &rest u) (list* x y z u)))
3432  (list (test-mc69-18 'a) (test-mc69-18 'a 'b) (test-mc69-18 'a 'b 'c) (test-mc69-18 'a 'b 'c 'd) (test-mc69-18 'a 'b 'c 'd 'e)))
3433(("xyz" "def" RESULT (A) (A NIL NIL))
3434 ("xyz" "def" RESULT (A B) (A B NIL))
3435 ("xyz" "def" RESULT (A B C) (A B C))
3436 ("xyz" "def" RESULT (A B C D) (A B C D))
3437 ("xyz" "def" RESULT (A B C D E) (A B C D E)))
3438
3439(progn
3440  (defgeneric test-mc69-19 (x &optional y z u &rest v)
3441    (:method-combination mc69 "xyz")
3442    (:method (x &optional y z u &rest v) (list* x y z u v)))
3443  (list (test-mc69-19 'a) (test-mc69-19 'a 'b) (test-mc69-19 'a 'b 'c) (test-mc69-19 'a 'b 'c 'd) (test-mc69-19 'a 'b 'c 'd 'e) (test-mc69-19 'a 'b 'c 'd 'e 'f)))
3444(("xyz" "def" RESULT (A) (A NIL NIL NIL))
3445 ("xyz" "def" RESULT (A B) (A B NIL NIL))
3446 ("xyz" "def" RESULT (A B C) (A B C NIL))
3447 ("xyz" "def" RESULT (A B C D) (A B C D))
3448 ("xyz" "def" RESULT (A B C D E) (A B C D E))
3449 ("xyz" "def" RESULT (A B C D E F) (A B C D E F)))
3450
3451; Check :arguments with &whole and required, optional and rest arguments.
3452(define-method-combination mc70 (opt1 &optional (opt2 "def")) ((all *))
3453  (:arguments &whole whole a1 a2 &optional (o1 'def1) (o2 'def2) &rest r)
3454  `(LIST ',opt1 ',opt2 'RESULT ,whole ,a1 ,a2 ,o1 ,o2 ,r (CALL-METHOD ,(first all))))
3455MC70
3456
3457(progn
3458  (defgeneric test-mc70-1 ()
3459    (:method-combination mc70 "xyz")
3460    (:method () '()))
3461  (test-mc70-1))
3462("xyz" "def" RESULT () NIL NIL DEF1 DEF2 () ())
3463
3464(progn
3465  (defgeneric test-mc70-2 (x)
3466    (:method-combination mc70 "xyz")
3467    (:method (x) (list x)))
3468  (test-mc70-2 'a))
3469("xyz" "def" RESULT (A) A NIL DEF1 DEF2 () (A))
3470
3471(progn
3472  (defgeneric test-mc70-3 (x y)
3473    (:method-combination mc70 "xyz")
3474    (:method (x y) (list x y)))
3475  (test-mc70-3 'a 'b))
3476("xyz" "def" RESULT (A B) A B DEF1 DEF2 () (A B))
3477
3478(progn
3479  (defgeneric test-mc70-4 (x y z)
3480    (:method-combination mc70 "xyz")
3481    (:method (x y z) (list x y z)))
3482  (test-mc70-4 'a 'b 'c))
3483("xyz" "def" RESULT (A B C) A B DEF1 DEF2 () (A B C))
3484
3485(progn
3486  (defgeneric test-mc70-5 (x &optional y)
3487    (:method-combination mc70 "xyz")
3488    (:method (x &optional y) (list x y)))
3489  (list (test-mc70-5 'a) (test-mc70-5 'a 'b)))
3490(("xyz" "def" RESULT (A) A NIL DEF1 DEF2 () (A NIL))
3491 ("xyz" "def" RESULT (A B) A NIL B DEF2 () (A B)))
3492
3493(progn
3494  (defgeneric test-mc70-6 (x y &optional z)
3495    (:method-combination mc70 "xyz")
3496    (:method (x y &optional z) (list x y z)))
3497  (list (test-mc70-6 'a 'b) (test-mc70-6 'a 'b 'c)))
3498(("xyz" "def" RESULT (A B) A B DEF1 DEF2 () (A B NIL))
3499 ("xyz" "def" RESULT (A B C) A B C DEF2 () (A B C)))
3500
3501(progn
3502  (defgeneric test-mc70-7 (x y z &optional u)
3503    (:method-combination mc70 "xyz")
3504    (:method (x y z &optional u) (list x y z u)))
3505  (list (test-mc70-7 'a 'b 'c) (test-mc70-7 'a 'b 'c 'd)))
3506(("xyz" "def" RESULT (A B C) A B DEF1 DEF2 () (A B C NIL))
3507 ("xyz" "def" RESULT (A B C D) A B D DEF2 () (A B C D)))
3508
3509(progn
3510  (defgeneric test-mc70-8 (x &optional y z)
3511    (:method-combination mc70 "xyz")
3512    (:method (x &optional y z) (list x y z)))
3513  (list (test-mc70-8 'a) (test-mc70-8 'a 'b) (test-mc70-8 'a 'b 'c)))
3514(("xyz" "def" RESULT (A) A NIL DEF1 DEF2 () (A NIL NIL))
3515 ("xyz" "def" RESULT (A B) A NIL B DEF2 () (A B NIL))
3516 ("xyz" "def" RESULT (A B C) A NIL B C () (A B C)))
3517
3518(progn
3519  (defgeneric test-mc70-9 (x y &optional z u)
3520    (:method-combination mc70 "xyz")
3521    (:method (x y &optional z u) (list x y z u)))
3522  (list (test-mc70-9 'a 'b) (test-mc70-9 'a 'b 'c) (test-mc70-9 'a 'b 'c 'd)))
3523(("xyz" "def" RESULT (A B) A B DEF1 DEF2 () (A B NIL NIL))
3524 ("xyz" "def" RESULT (A B C) A B C DEF2 () (A B C NIL))
3525 ("xyz" "def" RESULT (A B C D) A B C D () (A B C D)))
3526
3527(progn
3528  (defgeneric test-mc70-10 (x y z &optional u v)
3529    (:method-combination mc70 "xyz")
3530    (:method (x y z &optional u v) (list x y z u v)))
3531  (list (test-mc70-10 'a 'b 'c) (test-mc70-10 'a 'b 'c 'd) (test-mc70-10 'a 'b 'c 'd 'e)))
3532(("xyz" "def" RESULT (A B C) A B DEF1 DEF2 () (A B C NIL NIL))
3533 ("xyz" "def" RESULT (A B C D) A B D DEF2 () (A B C D NIL))
3534 ("xyz" "def" RESULT (A B C D E) A B D E () (A B C D E)))
3535
3536(progn
3537  (defgeneric test-mc70-11 (x &optional y z u)
3538    (:method-combination mc70 "xyz")
3539    (:method (x &optional y z u) (list x y z u)))
3540  (list (test-mc70-11 'a) (test-mc70-11 'a 'b) (test-mc70-11 'a 'b 'c) (test-mc70-11 'a 'b 'c 'd)))
3541(("xyz" "def" RESULT (A) A NIL DEF1 DEF2 () (A NIL NIL NIL))
3542 ("xyz" "def" RESULT (A B) A NIL B DEF2 () (A B NIL NIL))
3543 ("xyz" "def" RESULT (A B C) A NIL B C () (A B C NIL))
3544 ("xyz" "def" RESULT (A B C D) A NIL B C () (A B C D)))
3545
3546(progn
3547  (defgeneric test-mc70-12 (x y &optional z u v)
3548    (:method-combination mc70 "xyz")
3549    (:method (x y &optional z u v) (list x y z u v)))
3550  (list (test-mc70-12 'a 'b) (test-mc70-12 'a 'b 'c) (test-mc70-12 'a 'b 'c 'd) (test-mc70-12 'a 'b 'c 'd 'e)))
3551(("xyz" "def" RESULT (A B) A B DEF1 DEF2 () (A B NIL NIL NIL))
3552 ("xyz" "def" RESULT (A B C) A B C DEF2 () (A B C NIL NIL))
3553 ("xyz" "def" RESULT (A B C D) A B C D () (A B C D NIL))
3554 ("xyz" "def" RESULT (A B C D E) A B C D () (A B C D E)))
3555
3556(progn
3557  (defgeneric test-mc70-13 (x y z &optional u v w)
3558    (:method-combination mc70 "xyz")
3559    (:method (x y z &optional u v w) (list x y z u v w)))
3560  (list (test-mc70-13 'a 'b 'c) (test-mc70-13 'a 'b 'c 'd) (test-mc70-13 'a 'b 'c 'd 'e) (test-mc70-13 'a 'b 'c 'd 'e 'f)))
3561(("xyz" "def" RESULT (A B C) A B DEF1 DEF2 () (A B C NIL NIL NIL))
3562 ("xyz" "def" RESULT (A B C D) A B D DEF2 () (A B C D NIL NIL))
3563 ("xyz" "def" RESULT (A B C D E) A B D E () (A B C D E NIL))
3564 ("xyz" "def" RESULT (A B C D E F) A B D E () (A B C D E F)))
3565
3566(progn
3567  (defgeneric test-mc70-14 (x &rest y)
3568    (:method-combination mc70 "xyz")
3569    (:method (x &rest y) (list* x y)))
3570  (list (test-mc70-14 'a) (test-mc70-14 'a 'b) (test-mc70-14 'a 'b 'c)))
3571(("xyz" "def" RESULT (A) A NIL DEF1 DEF2 () (A))
3572 ("xyz" "def" RESULT (A B) A NIL DEF1 DEF2 (B) (A B))
3573 ("xyz" "def" RESULT (A B C) A NIL DEF1 DEF2 (B C) (A B C)))
3574
3575(progn
3576  (defgeneric test-mc70-15 (x y &rest z)
3577    (:method-combination mc70 "xyz")
3578    (:method (x y &rest z) (list* x y z)))
3579  (list (test-mc70-15 'a 'b) (test-mc70-15 'a 'b 'c) (test-mc70-15 'a 'b 'c 'd)))
3580(("xyz" "def" RESULT (A B) A B DEF1 DEF2 () (A B))
3581 ("xyz" "def" RESULT (A B C) A B DEF1 DEF2 (C) (A B C))
3582 ("xyz" "def" RESULT (A B C D) A B DEF1 DEF2 (C D) (A B C D)))
3583
3584(progn
3585  (defgeneric test-mc70-16 (x y z &rest u)
3586    (:method-combination mc70 "xyz")
3587    (:method (x y z &rest u) (list* x y z u)))
3588  (list (test-mc70-16 'a 'b 'c) (test-mc70-16 'a 'b 'c 'd) (test-mc70-16 'a 'b 'c 'd 'e)))
3589(("xyz" "def" RESULT (A B C) A B DEF1 DEF2 () (A B C))
3590 ("xyz" "def" RESULT (A B C D) A B DEF1 DEF2 (D) (A B C D))
3591 ("xyz" "def" RESULT (A B C D E) A B DEF1 DEF2 (D E) (A B C D E)))
3592
3593(progn
3594  (defgeneric test-mc70-17 (x &optional y &rest z)
3595    (:method-combination mc70 "xyz")
3596    (:method (x &optional y &rest z) (list* x y z)))
3597  (list (test-mc70-17 'a) (test-mc70-17 'a 'b) (test-mc70-17 'a 'b 'c) (test-mc70-17 'a 'b 'c 'd)))
3598(("xyz" "def" RESULT (A) A NIL DEF1 DEF2 () (A NIL))
3599 ("xyz" "def" RESULT (A B) A NIL B DEF2 () (A B))
3600 ("xyz" "def" RESULT (A B C) A NIL B DEF2 (C) (A B C))
3601 ("xyz" "def" RESULT (A B C D) A NIL B DEF2 (C D) (A B C D)))
3602
3603(progn
3604  (defgeneric test-mc70-18 (x &optional y z &rest u)
3605    (:method-combination mc70 "xyz")
3606    (:method (x &optional y z &rest u) (list* x y z u)))
3607  (list (test-mc70-18 'a) (test-mc70-18 'a 'b) (test-mc70-18 'a 'b 'c) (test-mc70-18 'a 'b 'c 'd) (test-mc70-18 'a 'b 'c 'd 'e)))
3608(("xyz" "def" RESULT (A) A NIL DEF1 DEF2 () (A NIL NIL))
3609 ("xyz" "def" RESULT (A B) A NIL B DEF2 () (A B NIL))
3610 ("xyz" "def" RESULT (A B C) A NIL B C () (A B C))
3611 ("xyz" "def" RESULT (A B C D) A NIL B C (D) (A B C D))
3612 ("xyz" "def" RESULT (A B C D E) A NIL B C (D E) (A B C D E)))
3613
3614(progn
3615  (defgeneric test-mc70-19 (x &optional y z u &rest v)
3616    (:method-combination mc70 "xyz")
3617    (:method (x &optional y z u &rest v) (list* x y z u v)))
3618  (list (test-mc70-19 'a) (test-mc70-19 'a 'b) (test-mc70-19 'a 'b 'c) (test-mc70-19 'a 'b 'c 'd) (test-mc70-19 'a 'b 'c 'd 'e) (test-mc70-19 'a 'b 'c 'd 'e 'f)))
3619(("xyz" "def" RESULT (A) A NIL DEF1 DEF2 () (A NIL NIL NIL))
3620 ("xyz" "def" RESULT (A B) A NIL B DEF2 () (A B NIL NIL))
3621 ("xyz" "def" RESULT (A B C) A NIL B C () (A B C NIL))
3622 ("xyz" "def" RESULT (A B C D) A NIL B C () (A B C D))
3623 ("xyz" "def" RESULT (A B C D E) A NIL B C (E) (A B C D E))
3624 ("xyz" "def" RESULT (A B C D E F) A NIL B C (E F) (A B C D E F)))
3625
3626; Check :arguments with only optional arguments but with svars.
3627(define-method-combination mc71 (opt1 &optional (opt2 "def")) ((all *))
3628  (:arguments &optional (o1 'def1 os1) (o2 'def2 os2))
3629  `(LIST ',opt1 ',opt2 'RESULT ,o1 ,o2 ,os1 ,os2 (CALL-METHOD ,(first all))))
3630MC71
3631
3632(progn
3633  (defgeneric test-mc71-1 (x)
3634    (:method-combination mc71 "xyz")
3635    (:method (x) (list x)))
3636  (test-mc71-1 'a))
3637("xyz" "def" RESULT DEF1 DEF2 NIL NIL (A))
3638
3639(progn
3640  (defgeneric test-mc71-2 (x &optional y)
3641    (:method-combination mc71 "xyz")
3642    (:method (x &optional y) (list x y)))
3643  (list (test-mc71-2 'a) (test-mc71-2 'a 'b)))
3644(("xyz" "def" RESULT DEF1 DEF2 NIL NIL (A NIL))
3645 ("xyz" "def" RESULT B DEF2 T NIL (A B)))
3646
3647(progn
3648  (defgeneric test-mc71-3 (x &optional y z)
3649    (:method-combination mc71 "xyz")
3650    (:method (x &optional y z) (list x y z)))
3651  (list (test-mc71-3 'a) (test-mc71-3 'a 'b) (test-mc71-3 'a 'b 'c)))
3652(("xyz" "def" RESULT DEF1 DEF2 NIL NIL (A NIL NIL))
3653 ("xyz" "def" RESULT B DEF2 T NIL (A B NIL))
3654 ("xyz" "def" RESULT B C T T (A B C)))
3655
3656(progn
3657  (defgeneric test-mc71-4 (x &optional y z u)
3658    (:method-combination mc71 "xyz")
3659    (:method (x &optional y z u) (list x y z u)))
3660  (list (test-mc71-4 'a) (test-mc71-4 'a 'b) (test-mc71-4 'a 'b 'c) (test-mc71-4 'a 'b 'c 'd)))
3661(("xyz" "def" RESULT DEF1 DEF2 NIL NIL (A NIL NIL NIL))
3662 ("xyz" "def" RESULT B DEF2 T NIL (A B NIL NIL))
3663 ("xyz" "def" RESULT B C T T (A B C NIL))
3664 ("xyz" "def" RESULT B C T T (A B C D)))
3665
3666(progn
3667  (defgeneric test-mc71-5 (x &rest y)
3668    (:method-combination mc71 "xyz")
3669    (:method (x &rest y) (list* x y)))
3670  (list (test-mc71-5 'a) (test-mc71-5 'a 'b) (test-mc71-5 'a 'b 'c)))
3671(("xyz" "def" RESULT DEF1 DEF2 NIL NIL (A))
3672 ("xyz" "def" RESULT DEF1 DEF2 NIL NIL (A B))
3673 ("xyz" "def" RESULT DEF1 DEF2 NIL NIL (A B C)))
3674
3675(progn
3676  (defgeneric test-mc71-6 (x &optional y &rest z)
3677    (:method-combination mc71 "xyz")
3678    (:method (x &optional y &rest z) (list* x y z)))
3679  (list (test-mc71-6 'a) (test-mc71-6 'a 'b) (test-mc71-6 'a 'b 'c)))
3680(("xyz" "def" RESULT DEF1 DEF2 NIL NIL (A NIL))
3681 ("xyz" "def" RESULT B DEF2 T NIL (A B))
3682 ("xyz" "def" RESULT B DEF2 T NIL (A B C)))
3683
3684(progn
3685  (defgeneric test-mc71-7 (x &optional y z &rest u)
3686    (:method-combination mc71 "xyz")
3687    (:method (x &optional y z &rest u) (list* x y z u)))
3688  (list (test-mc71-7 'a) (test-mc71-7 'a 'b) (test-mc71-7 'a 'b 'c) (test-mc71-7 'a 'b 'c 'd)))
3689(("xyz" "def" RESULT DEF1 DEF2 NIL NIL (A NIL NIL))
3690 ("xyz" "def" RESULT B DEF2 T NIL (A B NIL))
3691 ("xyz" "def" RESULT B C T T (A B C))
3692 ("xyz" "def" RESULT B C T T (A B C D)))
3693
3694; Check :arguments with required, optional and key arguments and key-svars.
3695(define-method-combination mc72 (opt1 &optional (opt2 "def")) ((all *))
3696  (:arguments a1 a2 &optional (o1 'def1) (o2 'def2) &key (test 'EQ test-p) (test-not 'NEQ test-not-p))
3697  `(LIST ',opt1 ',opt2 'RESULT ,a1 ,a2 ,o1 ,o2 ,test ,test-not ,test-p ,test-not-p (CALL-METHOD ,(first all))))
3698MC72
3699
3700(progn
3701  (defgeneric test-mc72-1 (x &optional y)
3702    (:method-combination mc72 "xyz")
3703    (:method (x &optional y) (list x y)))
3704  (list (test-mc72-1 'a) (test-mc72-1 'a 'b)))
3705(("xyz" "def" RESULT A NIL DEF1 DEF2 EQ NEQ NIL NIL (A NIL))
3706 ("xyz" "def" RESULT A NIL B DEF2 EQ NEQ NIL NIL (A B)))
3707
3708(progn
3709  (defgeneric test-mc72-2 (x y z &optional u v w)
3710    (:method-combination mc72 "xyz")
3711    (:method (x y z &optional u v w) (list x y z u v w)))
3712  (list (test-mc72-2 'a 'b 'c) (test-mc72-2 'a 'b 'c 'd) (test-mc72-2 'a 'b 'c 'd 'e) (test-mc72-2 'a 'b 'c 'd 'e 'f)))
3713(("xyz" "def" RESULT A B DEF1 DEF2 EQ NEQ NIL NIL (A B C NIL NIL NIL))
3714 ("xyz" "def" RESULT A B D DEF2 EQ NEQ NIL NIL (A B C D NIL NIL))
3715 ("xyz" "def" RESULT A B D E EQ NEQ NIL NIL (A B C D E NIL))
3716 ("xyz" "def" RESULT A B D E EQ NEQ NIL NIL (A B C D E F)))
3717
3718(progn
3719  (defgeneric test-mc72-3 (x &rest y)
3720    (:method-combination mc72 "xyz")
3721    (:method (x &rest y) (list* x y)))
3722  (list (test-mc72-3 'a) (test-mc72-3 'a 'b 'c)
3723        (test-mc72-3 'a :test-not 'nequal)
3724        (test-mc72-3 'a :test 'eq :test-not 'nequal)
3725        (test-mc72-3 'a :test-not 'nequal :test 'eql :test-not 'nequalp)))
3726(("xyz" "def" RESULT A NIL DEF1 DEF2 EQ NEQ NIL NIL (A))
3727 ("xyz" "def" RESULT A NIL DEF1 DEF2 EQ NEQ NIL NIL (A B C))
3728 ("xyz" "def" RESULT A NIL DEF1 DEF2 EQ NEQUAL NIL T (A :TEST-NOT NEQUAL))
3729 ("xyz" "def" RESULT A NIL DEF1 DEF2 EQ NEQUAL T T (A :TEST EQ :TEST-NOT NEQUAL))
3730 ("xyz" "def" RESULT A NIL DEF1 DEF2 EQL NEQUAL T T (A :TEST-NOT NEQUAL :TEST EQL :TEST-NOT NEQUALP)))
3731
3732(progn
3733  (defgeneric test-mc72-4 (x &rest y)
3734    (:method-combination mc72 "xyz")
3735    (:method (x &rest y) (list* x y)))
3736  (test-mc72-4 'a 'b))
3737ERROR
3738
3739(progn
3740  (defgeneric test-mc72-5 (x y z &rest u)
3741    (:method-combination mc72 "xyz")
3742    (:method (x y z &rest u) (list* x y z u)))
3743  (list (test-mc72-5 'a :test 'eq) (test-mc72-5 'a :test 'eq 'd 'e)
3744        (test-mc72-5 'a :test 'eq :test-not 'nequal)
3745        (test-mc72-5 'a :test 'eq :test 'eq :test-not 'nequal)
3746        (test-mc72-5 'a :test 'eq :test-not 'nequal :test 'eql :test-not 'nequalp)))
3747(("xyz" "def" RESULT A :TEST DEF1 DEF2 EQ NEQ NIL NIL (A :TEST EQ))
3748 ("xyz" "def" RESULT A :TEST DEF1 DEF2 EQ NEQ NIL NIL (A :TEST EQ D E))
3749 ("xyz" "def" RESULT A :TEST DEF1 DEF2 EQ NEQUAL NIL T (A :TEST EQ :TEST-NOT NEQUAL))
3750 ("xyz" "def" RESULT A :TEST DEF1 DEF2 EQ NEQUAL T T (A :TEST EQ :TEST EQ :TEST-NOT NEQUAL))
3751 ("xyz" "def" RESULT A :TEST DEF1 DEF2 EQL NEQUAL T T (A :TEST EQ :TEST-NOT NEQUAL :TEST EQL :TEST-NOT NEQUALP)))
3752
3753(progn
3754  (defgeneric test-mc72-6 (x &optional y z u &rest v)
3755    (:method-combination mc72 "xyz")
3756    (:method (x &optional y z u &rest v) (list* x y z u v)))
3757  (list (test-mc72-6 'a) (test-mc72-6 'a 'b 'c)
3758        (test-mc72-6 'a :test 'eq 'd :test-not 'nequal)
3759        (test-mc72-6 'a :test 'eq 'd :test 'eq :test-not 'nequal)
3760        (test-mc72-6 'a :test 'eq 'd :test-not 'nequal :test 'eql :test-not 'nequalp)))
3761(("xyz" "def" RESULT A NIL DEF1 DEF2 EQ NEQ NIL NIL (A NIL NIL NIL))
3762 ("xyz" "def" RESULT A NIL B C EQ NEQ NIL NIL (A B C NIL))
3763 ("xyz" "def" RESULT A NIL :TEST EQ EQ NEQUAL NIL T (A :TEST EQ D :TEST-NOT NEQUAL))
3764 ("xyz" "def" RESULT A NIL :TEST EQ EQ NEQUAL T T (A :TEST EQ D :TEST EQ :TEST-NOT NEQUAL))
3765 ("xyz" "def" RESULT A NIL :TEST EQ EQL NEQUAL T T (A :TEST EQ D :TEST-NOT NEQUAL :TEST EQL :TEST-NOT NEQUALP)))
3766
3767; Check that it's possible to provide 'redo' and 'return' restarts for each
3768; method invocation.
3769(progn
3770  (defun prompt-for-new-values ()
3771    (format *debug-io* "~&New values: ")
3772    (list (read *debug-io*)))
3773  (defun add-method-restarts (form method)
3774    (let ((block (gensym))
3775          (tag (gensym)))
3776      `(BLOCK ,block
3777         (TAGBODY
3778           ,tag
3779           (RETURN-FROM ,block
3780             (RESTART-CASE ,form
3781               (METHOD-REDO ()
3782                 :REPORT (LAMBDA (STREAM) (FORMAT STREAM "Try calling ~S again." ,method))
3783                 (GO ,tag))
3784               (METHOD-RETURN (L)
3785                 :REPORT (LAMBDA (STREAM) (FORMAT STREAM "Specify return values for ~S call." ,method))
3786                 :INTERACTIVE (LAMBDA () (PROMPT-FOR-NEW-VALUES))
3787                 (RETURN-FROM ,block (VALUES-LIST L)))))))))
3788  (defun convert-effective-method (efm)
3789    (if (consp efm)
3790      (if (eq (car efm) 'CALL-METHOD)
3791        (let ((method-list (third efm)))
3792          (if (or (typep (first method-list) 'method) (rest method-list))
3793            ; Reduce the case of multiple methods to a single one.
3794            ; Make the call to the next-method explicit.
3795            (convert-effective-method
3796              `(CALL-METHOD ,(second efm)
3797                 ((MAKE-METHOD
3798                    (CALL-METHOD ,(first method-list) ,(rest method-list))))))
3799            ; Now the case of at most one method.
3800            (if (typep (second efm) 'method)
3801              ; Wrap the method call in a RESTART-CASE.
3802              (add-method-restarts
3803                (cons (convert-effective-method (car efm))
3804                      (convert-effective-method (cdr efm)))
3805                (second efm))
3806              ; Normal recursive processing.
3807              (cons (convert-effective-method (car efm))
3808                    (convert-effective-method (cdr efm))))))
3809        (cons (convert-effective-method (car efm))
3810              (convert-effective-method (cdr efm))))
3811      efm))
3812  (define-method-combination standard-with-restarts ()
3813         ((around (:around))
3814          (before (:before))
3815          (primary () :required t)
3816          (after (:after)))
3817    (flet ((call-methods-sequentially (methods)
3818             (mapcar #'(lambda (method)
3819                         `(CALL-METHOD ,method))
3820                     methods)))
3821      (let ((form (if (or before after (rest primary))
3822                    `(MULTIPLE-VALUE-PROG1
3823                       (PROGN
3824                         ,@(call-methods-sequentially before)
3825                         (CALL-METHOD ,(first primary) ,(rest primary)))
3826                       ,@(call-methods-sequentially (reverse after)))
3827                    `(CALL-METHOD ,(first primary)))))
3828        (when around
3829          (setq form
3830                `(CALL-METHOD ,(first around)
3831                              (,@(rest around) (MAKE-METHOD ,form)))))
3832        (convert-effective-method form))))
3833  (defgeneric testgf16 (x) (:method-combination standard-with-restarts))
3834  (defclass testclass16a () ())
3835  (defclass testclass16b (testclass16a) ())
3836  (defclass testclass16c (testclass16a) ())
3837  (defclass testclass16d (testclass16b testclass16c) ())
3838  (defmethod testgf16 ((x testclass16a))
3839    (list 'a
3840          (not (null (find-restart 'method-redo)))
3841          (not (null (find-restart 'method-return)))))
3842  (defmethod testgf16 ((x testclass16b))
3843    (cons 'b (call-next-method)))
3844  (defmethod testgf16 ((x testclass16c))
3845    (cons 'c (call-next-method)))
3846  (defmethod testgf16 ((x testclass16d))
3847    (cons 'd (call-next-method)))
3848  (testgf16 (make-instance 'testclass16d)))
3849(D B C A T T)
3850
3851
3852;; Method combination with user-defined methods
3853
3854(progn
3855  (defclass user-method (standard-method) (myslot))
3856  t)
3857T
3858
3859(defmacro def-user-method (name &rest rest)
3860  (let* ((lambdalist-position (position-if #'listp rest))
3861         (qualifiers (subseq rest 0 lambdalist-position))
3862         (lambdalist (elt rest lambdalist-position))
3863         (body (subseq rest (+ lambdalist-position 1)))
3864         (required-part (subseq lambdalist 0 (or (position-if #'(lambda (x) (member x lambda-list-keywords)) lambdalist) (length lambdalist))))
3865         (specializers (mapcar #'find-class (mapcar #'(lambda (x) (if (consp x) (second x) 't)) required-part)))
3866         (unspecialized-required-part (mapcar #'(lambda (x) (if (consp x) (first x) x)) required-part))
3867         (unspecialized-lambdalist (append unspecialized-required-part (subseq lambdalist (length required-part)))))
3868    `(PROGN
3869       (ADD-METHOD #',name
3870         (MAKE-INSTANCE 'user-method
3871           :QUALIFIERS ',qualifiers
3872           :LAMBDA-LIST ',unspecialized-lambdalist
3873           :SPECIALIZERS ',specializers
3874           :FUNCTION
3875             #'(LAMBDA (ARGUMENTS NEXT-METHODS-LIST)
3876                 (FLET ((NEXT-METHOD-P () NEXT-METHODS-LIST)
3877                        (CALL-NEXT-METHOD (&REST NEW-ARGUMENTS)
3878                          (UNLESS NEW-ARGUMENTS (SETQ NEW-ARGUMENTS ARGUMENTS))
3879                          (IF (NULL NEXT-METHODS-LIST)
3880                            (ERROR "no next method for arguments ~:S" ARGUMENTS)
3881                            (FUNCALL (#+SBCL SB-PCL:METHOD-FUNCTION
3882                                      #+CMU MOP:METHOD-FUNCTION
3883                                      #-(or SBCL CMU) METHOD-FUNCTION
3884                                       (FIRST NEXT-METHODS-LIST))
3885                                     NEW-ARGUMENTS (REST NEXT-METHODS-LIST)))))
3886                   (APPLY #'(LAMBDA ,unspecialized-lambdalist ,@body) ARGUMENTS)))))
3887       ',name)))
3888DEF-USER-METHOD
3889
3890; Single method.
3891(progn
3892  (defgeneric test-um01 (x y))
3893  (def-user-method test-um01 ((x symbol) (y symbol)) (list x y (next-method-p)))
3894  (test-um01 'a 'b))
3895(A B NIL)
3896
3897; First among three primary methods.
3898(progn
3899  (defgeneric test-um02 (x))
3900  (def-user-method test-um02 ((x integer))
3901    (list* 'integer x (not (null (next-method-p))) (call-next-method)))
3902  (defmethod test-um02 ((x rational))
3903    (list* 'rational x (not (null (next-method-p))) (call-next-method)))
3904  (defmethod test-um02 ((x real))
3905    (list 'real x (not (null (next-method-p)))))
3906  (test-um02 17))
3907(INTEGER 17 T RATIONAL 17 T REAL 17 NIL)
3908
3909; Second among three primary methods.
3910(progn
3911  (defgeneric test-um03 (x))
3912  (defmethod test-um03 ((x integer))
3913    (list* 'integer x (not (null (next-method-p))) (call-next-method)))
3914  (def-user-method test-um03 ((x rational))
3915    (list* 'rational x (not (null (next-method-p))) (call-next-method)))
3916  (defmethod test-um03 ((x real))
3917    (list 'real x (not (null (next-method-p)))))
3918  (test-um03 17))
3919(INTEGER 17 T RATIONAL 17 T REAL 17 NIL)
3920
3921; Last among three primary methods.
3922(progn
3923  (defgeneric test-um04 (x))
3924  (defmethod test-um04 ((x integer))
3925    (list* 'integer x (not (null (next-method-p))) (call-next-method)))
3926  (defmethod test-um04 ((x rational))
3927    (list* 'rational x (not (null (next-method-p))) (call-next-method)))
3928  (def-user-method test-um04 ((x real))
3929    (list 'real x (not (null (next-method-p)))))
3930  (test-um04 17))
3931(INTEGER 17 T RATIONAL 17 T REAL 17 NIL)
3932
3933; First among two before methods.
3934(let ((results nil))
3935  (defgeneric test-um05 (x))
3936  (defmethod test-um05 (x) (push 'PRIMARY results) (push x results))
3937  (def-user-method test-um05 :before ((x integer)) (push 'BEFORE-INTEGER results) (push x results))
3938  (defmethod test-um05 :before ((x real)) (push 'BEFORE-REAL results) (push x results))
3939  (test-um05 17)
3940  (nreverse results))
3941(BEFORE-INTEGER 17 BEFORE-REAL 17 PRIMARY 17)
3942
3943; Last among two before methods.
3944(let ((results nil))
3945  (defgeneric test-um06 (x))
3946  (defmethod test-um06 (x) (push 'PRIMARY results) (push x results))
3947  (defmethod test-um06 :before ((x integer)) (push 'BEFORE-INTEGER results) (push x results))
3948  (def-user-method test-um06 :before ((x real)) (push 'BEFORE-REAL results) (push x results))
3949  (test-um06 17)
3950  (nreverse results))
3951(BEFORE-INTEGER 17 BEFORE-REAL 17 PRIMARY 17)
3952
3953; First among two after methods.
3954(let ((results nil))
3955  (defgeneric test-um07 (x))
3956  (defmethod test-um07 (x) (push 'PRIMARY results) (push x results))
3957  (defmethod test-um07 :after ((x integer)) (push 'AFTER-INTEGER results) (push x results))
3958  (def-user-method test-um07 :after ((x real)) (push 'AFTER-REAL results) (push x results))
3959  (test-um07 17)
3960  (nreverse results))
3961(PRIMARY 17 AFTER-REAL 17 AFTER-INTEGER 17)
3962
3963; Last among two after methods.
3964(let ((results nil))
3965  (defgeneric test-um08 (x))
3966  (defmethod test-um08 (x) (push 'PRIMARY results) (push x results))
3967  (def-user-method test-um08 :after ((x integer)) (push 'AFTER-INTEGER results) (push x results))
3968  (defmethod test-um08 :after ((x real)) (push 'AFTER-REAL results) (push x results))
3969  (test-um08 17)
3970  (nreverse results))
3971(PRIMARY 17 AFTER-REAL 17 AFTER-INTEGER 17)
3972
3973; First among three around methods.
3974(progn
3975  (defgeneric test-um10 (x))
3976  (defmethod test-um10 ((x integer))
3977    (list* 'integer x (not (null (next-method-p))) (call-next-method)))
3978  (defmethod test-um10 ((x rational))
3979    (list* 'rational x (not (null (next-method-p))) (call-next-method)))
3980  (defmethod test-um10 ((x real))
3981    (list 'real x (not (null (next-method-p)))))
3982  (defmethod test-um10 :after ((x real)))
3983  (def-user-method test-um10 :around ((x integer))
3984    (list* 'around-integer x (not (null (next-method-p))) (call-next-method)))
3985  (defmethod test-um10 :around ((x rational))
3986    (list* 'around-rational x (not (null (next-method-p))) (call-next-method)))
3987  (defmethod test-um10 :around ((x real))
3988    (list* 'around-real x (not (null (next-method-p))) (call-next-method)))
3989  (test-um10 17))
3990(AROUND-INTEGER 17 T AROUND-RATIONAL 17 T AROUND-REAL 17 T INTEGER 17 T RATIONAL 17 T REAL 17 NIL)
3991
3992; Second among three around methods.
3993(progn
3994  (defgeneric test-um11 (x))
3995  (defmethod test-um11 ((x integer))
3996    (list* 'integer x (not (null (next-method-p))) (call-next-method)))
3997  (defmethod test-um11 ((x rational))
3998    (list* 'rational x (not (null (next-method-p))) (call-next-method)))
3999  (defmethod test-um11 ((x real))
4000    (list 'real x (not (null (next-method-p)))))
4001  (defmethod test-um11 :after ((x real)))
4002  (defmethod test-um11 :around ((x integer))
4003    (list* 'around-integer x (not (null (next-method-p))) (call-next-method)))
4004  (def-user-method test-um11 :around ((x rational))
4005    (list* 'around-rational x (not (null (next-method-p))) (call-next-method)))
4006  (defmethod test-um11 :around ((x real))
4007    (list* 'around-real x (not (null (next-method-p))) (call-next-method)))
4008  (test-um11 17))
4009(AROUND-INTEGER 17 T AROUND-RATIONAL 17 T AROUND-REAL 17 T INTEGER 17 T RATIONAL 17 T REAL 17 NIL)
4010
4011; Third among three around methods.
4012(progn
4013  (defgeneric test-um12 (x))
4014  (defmethod test-um12 ((x integer))
4015    (list* 'integer x (not (null (next-method-p))) (call-next-method)))
4016  (defmethod test-um12 ((x rational))
4017    (list* 'rational x (not (null (next-method-p))) (call-next-method)))
4018  (defmethod test-um12 ((x real))
4019    (list 'real x (not (null (next-method-p)))))
4020  (defmethod test-um12 :after ((x real)))
4021  (defmethod test-um12 :around ((x integer))
4022    (list* 'around-integer x (not (null (next-method-p))) (call-next-method)))
4023  (defmethod test-um12 :around ((x rational))
4024    (list* 'around-rational x (not (null (next-method-p))) (call-next-method)))
4025  (def-user-method test-um12 :around ((x real))
4026    (list* 'around-real x (not (null (next-method-p))) (call-next-method)))
4027  (test-um12 17))
4028(AROUND-INTEGER 17 T AROUND-RATIONAL 17 T AROUND-REAL 17 T INTEGER 17 T RATIONAL 17 T REAL 17 NIL)
4029
4030; Second among three around methods, and also a user-defined primary method.
4031(progn
4032  (defgeneric test-um13 (x))
4033  (defmethod test-um13 ((x integer))
4034    (list* 'integer x (not (null (next-method-p))) (call-next-method)))
4035  (def-user-method test-um13 ((x rational))
4036    (list* 'rational x (not (null (next-method-p))) (call-next-method)))
4037  (defmethod test-um13 ((x real))
4038    (list 'real x (not (null (next-method-p)))))
4039  (defmethod test-um13 :after ((x real)))
4040  (defmethod test-um13 :around ((x integer))
4041    (list* 'around-integer x (not (null (next-method-p))) (call-next-method)))
4042  (def-user-method test-um13 :around ((x rational))
4043    (list* 'around-rational x (not (null (next-method-p))) (call-next-method)))
4044  (defmethod test-um13 :around ((x real))
4045    (list* 'around-real x (not (null (next-method-p))) (call-next-method)))
4046  (test-um13 17))
4047(AROUND-INTEGER 17 T AROUND-RATIONAL 17 T AROUND-REAL 17 T INTEGER 17 T RATIONAL 17 T REAL 17 NIL)
4048
4049
4050#|
4051;; Check that invalid print-object methods yield a warning.
4052(progn
4053  (defclass foo128 () ())
4054  (defmethod print-object ((object foo128) stream)
4055    (print-unreadable-object (object stream :type t :identity t)
4056      (write "BLABLA" :stream stream)))
4057  (block nil
4058    (handler-bind ((WARNING #'(lambda (w) (declare (ignore w)) (return 'WARNING))))
4059      (prin1-to-string (make-instance 'foo128)))
4060    nil))
4061#+CLISP WARNING
4062#-CLISP NIL
4063|#
4064
4065
4066;; Test against bug in clos::%call-next-method and FUNCALL&SKIP&RETGF.
4067(progn
4068  (defclass foo129 ()
4069    ((x :initarg :x)))
4070  (defparameter *foo129-counter* 0)
4071  (defmethod initialize-instance ((instance foo129) &rest initargs &key (x '()))
4072    (incf *foo129-counter*) ; (format t "~&Initializing ~S  ~:S~%" instance x)
4073    (apply #'call-next-method instance :x (cons 'a x) initargs))
4074  (make-instance 'foo129)
4075  *foo129-counter*)
40761
4077
4078(progn
4079  (defclass foo130 ()
4080    ((x :initarg :x)))
4081  (defparameter *foo130-counter* 0)
4082  (locally (declare (compile))
4083    (defmethod initialize-instance ((instance foo130) &rest initargs &key (x '()))
4084      (incf *foo130-counter*) ; (format t "~&Initializing ~S  ~:S~%" instance x)
4085      (apply #'call-next-method instance :x (cons 'a x) initargs)))
4086  (make-instance 'foo130)
4087  *foo130-counter*)
40881
4089
4090;; Check that undefined classes are treated as undefined, even though they
4091;; are represented by a FORWARD-REFERENCED-CLASS.
4092(progn
4093  #+CLISP (setq custom:*forward-referenced-class-misdesign* t)
4094  (defclass foo131 (forwardclass01) ())
4095  t)
4096T
4097(find-class 'forwardclass01)
4098ERROR
4099(find-class 'forwardclass01 nil)
4100NIL
4101(typep 1 'forwardclass01)
4102ERROR
4103(locally (declare (compile)) (typep 1 'forwardclass01))
4104ERROR
4105(type-expand 'forwardclass01)
4106ERROR
4107(subtypep 'forwardclass01 't)
4108ERROR
4109(subtypep 'nil 'forwardclass01)
4110ERROR
4111#+CLISP (sys::subtype-integer 'forwardclass01)
4112#+CLISP NIL ; should also be ERROR
4113#+CLISP (sys::subtype-sequence 'forwardclass01)
4114#+CLISP NIL ; should also be ERROR
4115(defstruct (foo131a (:include forwardclass01)))
4116ERROR
4117(defmethod foo131b ((x forwardclass01)))
4118ERROR
4119;; Same thing with opposite setting of *forward-referenced-class-misdesign*.
4120(progn
4121  #+CLISP (setq custom:*forward-referenced-class-misdesign* nil)
4122  (defclass foo132 (forwardclass02) ())
4123  t)
4124T
4125(find-class 'forwardclass02)
4126ERROR
4127(find-class 'forwardclass02 nil)
4128NIL
4129(typep 1 'forwardclass02)
4130ERROR
4131(locally (declare (compile)) (typep 1 'forwardclass02))
4132ERROR
4133(type-expand 'forwardclass02)
4134ERROR
4135(subtypep 'forwardclass02 't)
4136ERROR
4137(subtypep 'nil 'forwardclass02)
4138ERROR
4139#+CLISP (sys::subtype-integer 'forwardclass02)
4140#+CLISP NIL ; should also be ERROR
4141#+CLISP (sys::subtype-sequence 'forwardclass02)
4142#+CLISP NIL ; should also be ERROR
4143(defstruct (foo132a (:include forwardclass02)))
4144ERROR
4145(defmethod foo132b ((x forwardclass02)))
4146ERROR
4147
4148;; Check that undefined classes yield an error in TYPEP and SUBTYPEP, but
4149;; that incomplete classes do not.
4150;; https://sourceforge.net/p/clisp/bugs/377/
4151(progn
4152  (defclass incomplete147 (undefined147) ())
4153  t)
4154T
4155(find-class 'undefined147)
4156ERROR
4157(typep 42 'undefined147)
4158ERROR
4159(subtypep 'undefined147 'number)
4160ERROR
4161(subtypep 'undefined147 'standard-object)
4162ERROR
4163(null (find-class 'incomplete147))
4164NIL
4165(typep 42 'incomplete147)
4166NIL
4167(multiple-value-list (subtypep 'incomplete147 'number))
4168(NIL T)
4169(multiple-value-list (subtypep 'incomplete147 'standard-object))
4170(NIL T) ; not (NIL NIL) because ANSI-CL says that SUBTYPEP on class names
4171        ; must never return "unknown"
4172
4173;; Check that methods that become active through a class redefinition
4174;; are actually invoked.
4175;; http://article.gmane.org/gmane.lisp.clisp.general:9582
4176;; https://sourceforge.net/p/clisp/mailman/message/12275493/
4177(let ((ret '()))
4178  (defclass mixin-foo-144 () ())
4179  (defclass class-foo-144 (mixin-foo-144) ())
4180  (defgeneric fun-144 (x))
4181  (defmethod fun-144 ((x class-foo-144))
4182    (push 'class-foo-144 ret))
4183  (defclass class-bar-144 () ())
4184  (defmethod fun-144 :after ((x class-bar-144))
4185    (push 'class-bar-144-after ret))
4186  ;; redefine class class-foo
4187  (defclass mixin-foo-144 (class-bar-144) ())
4188  (fun-144 (make-instance 'class-foo-144))
4189  (nreverse ret))
4190(CLASS-FOO-144 CLASS-BAR-144-AFTER)
4191
4192;; Similar, but call the generic function already before the redefinition.
4193(let ((ret ()))
4194  (defclass mixin-foo-145 () ())
4195  (defclass class-foo-145 (mixin-foo-145) ())
4196  (defgeneric fun-145 (x))
4197  (defmethod fun-145 ((x class-foo-145))
4198    (push 'class-foo-145 ret))
4199  (defclass class-bar-145 () ())
4200  (defmethod fun-145 :after ((x class-bar-145))
4201    (push 'class-bar-145-after ret))
4202  (let ((inst (make-instance 'class-foo-145)))
4203    (fun-145 inst)
4204    (setq ret '())
4205    ;; redefine class class-foo
4206    (defclass mixin-foo-145 (class-bar-145) ())
4207    (fun-145 inst)
4208    (nreverse ret)))
4209(CLASS-FOO-145 CLASS-BAR-145-AFTER)
4210
4211;; Check that when redefining a class with different slot initargs, the
4212;; new initargs are taken into account by make-instance.
4213(progn
4214  (defclass foo146 () (slot1))
4215  (make-instance 'foo146)
4216  (defclass foo146 () ((slot1 :initarg :foo)))
4217  (make-instance 'foo146 :foo 'any)
4218  t)
4219T
4220
4221;; Check that when redefining a class with different slot initargs, the
4222;; new initargs are taken into account by make-instance of subclasses.
4223(progn
4224  (defclass foo147 () (slot1))
4225  (defclass foosub147 (foo147) (slot2))
4226  (make-instance 'foosub147)
4227  (defclass foo147 () ((slot1 :initarg :foo)))
4228  (make-instance 'foosub147 :foo 'any)
4229  t)
4230T
4231
4232;; https://sourceforge.net/p/clisp/bugs/628/
4233(progn
4234  (defgeneric foo148 (object)
4235    (:method ((x list)) (declare (ignore x)) 'list)
4236    (:method ((x array)) (declare (ignore x)) 'array)
4237    (:method ((x sequence)) (declare (ignore x)) 'sequence))
4238  (foo148 '(1 2 3)))
4239LIST
4240
4241;; Check a particular use of Gray streams.
4242(progn (load (make-pathname :name "listeners" :type nil
4243                            :defaults *run-test-truename*))
4244       (with-open-stream (s1 (make-string-input-stream "("))
4245         (with-open-stream (s2 (make-string-input-stream "())"))
4246           (with-open-stream (l (make-instance 'listener-input-stream
4247                                               :stream s2))
4248             (with-open-stream (c (make-concatenated-stream s1 l))
4249               (read c))))))
4250(NIL)
4251
4252;; https://sourceforge.net/p/clisp/bugs/354/
4253(make-instance (make-instance 'standard-class :name 3))
4254ERROR
4255
4256(symbols-cleanup
4257 '(<C1> <C2> foo a b c f g *hl* hgen h testgf00 foo136 subclassp
4258   mlf-tester mlf-kill test-class1 test-class2 *t-list* *tmp-file* *foo*
4259   bar-const pos tree-with-parent *initform-executed-counter* foo64a
4260   foo64b foo64c foo64d abstract-position x-y-position
4261   rho-theta-position c0 c1 c2 c3 c4 c7 c8 foo60-a foo60-b foo61-a
4262   foo62-a foo62-b foo62-c foo63-a foo63-b foo63-c foo65a foo65b foo65c
4263   position-x position-y foo70 foo71 foo72 foo73 foo74 foo75 foo76 foo77
4264   foo80a foo80b foo81a foo81b foo82a foo82b foo83a foo83b foo84a foo84b
4265   foo85a foo85b foo86a foo86b foo87a foo87b foo88a foo88b foo88c foo89a
4266   foo89b foo89c foo90a foo90b foo90c foo91a foo91b foo91c foo92a foo92b
4267   foo93a foo93b foo94 foo95b foo96a foo96b foo97a foo97b foo100 foo101a
4268   foo101b foo102a foo102b foo102c foo103a foo103b foo103c foo104a
4269   foo104b foo104c foo105a foo105b foo105c foo106a foo106b foo106c
4270   foo107a foo107b foo108a foo108b foo109 foo116 foo117 foo118 foo119
4271   foo120 foo121 foo122 foo123 foo124 foo125 testclass31a testclass31b
4272   testclass31c testgf37 testclass40a testclass40b testclass40c testgf40
4273   testclass41a testclass41b testclass41c testgf41 testclass42a
4274   testclass42b testclass42c testgf42 testclass45a testclass45b
4275   testclass45c testgf45 testclass46a testclass46b testclass46c testgf46
4276   testclass47a testclass47b testclass47c testgf47 testclass48a
4277   testclass48b testclass48c testgf48 testclass49a testclass49b
4278   testclass49c testgf49 testclass50a testclass50b testclass50c testgf50
4279   class-0203 class-0204 class-0206a class-0206b reinit-class-01 foo126
4280   foo127 no-app-meth-gf-01 no-app-meth-gf-02 no-app-meth-gf-03
4281   no-prim-meth-gf-01 no-prim-meth-gf-02 no-prim-meth-gf-03
4282   test-mc-standard test-mc-standard-bad-qualifiers
4283   test-mc-standard-bad1 test-mc-standard-bad2 test-mc-standard-bad3
4284   test-mc-standard-bad4 test-mc-progn test-mc-append-1 test-mc-append-2
4285   test-mc-append-3 mc01 mc02 mc03 mc04 mc05 test-mc05-1 test-mc05-2
4286   test-mc05-3 test-mc05-4 test-mc05-5 test-mc05-6 mc06 test-mc06-1
4287   positive-integer-qualifier-p example-method-combination mc-test-piq
4288   w-args mc-test-w-args mc11 mc12 mc13 mc14 mc15 mc16 mc17 mc18 mc19
4289   mc20 mc21 mc22 mc23 mc24 mc25 test-mc25 mc26 test-mc26 mc27 test-mc27
4290   mc28 test-mc28 mc29 test-mc29 mc50 test-mc50-1 test-mc50-2
4291   test-mc50-3 mc51 test-mc51-1 test-mc51-2 test-mc51-3 test-mc51-4
4292   test-mc51-5 mc60 test-mc60-1 test-mc60-2 test-mc60-3 test-mc60-4 mc61
4293   test-mc61-1 test-mc61-2 test-mc61-3 test-mc61-4 test-mc61-5
4294   test-mc61-6 test-mc61-7 test-mc61-8 test-mc61-9 mc62 test-mc62-1
4295   test-mc62-2 test-mc62-3 test-mc62-4 test-mc62-5 test-mc62-6
4296   test-mc62-7 mc63 test-mc63-1 test-mc63-2 test-mc63-3 test-mc63-4 mc64
4297   test-mc64-1 test-mc64-2 test-mc64-3 test-mc64-4 test-mc64-5
4298   test-mc64-6 test-mc64-7 test-mc64-8 test-mc64-9 test-mc64-10
4299   test-mc64-11 test-mc64-12 test-mc64-13 test-mc64-14 test-mc64-15
4300   test-mc64-16 test-mc64-17 test-mc64-18 test-mc64-19 mc65 test-mc65-1
4301   test-mc65-2 test-mc65-3 test-mc65-4 test-mc65-5 test-mc65-6
4302   test-mc65-7 test-mc65-8 test-mc65-9 test-mc65-10 test-mc65-11
4303   test-mc65-12 test-mc65-13 test-mc65-14 test-mc65-15 test-mc65-16
4304   test-mc65-17 test-mc65-18 test-mc65-19 mc66 test-mc66-1 test-mc66-2
4305   test-mc66-3 test-mc66-4 test-mc66-5 test-mc66-6 test-mc66-7
4306   test-mc66-8 test-mc66-9 test-mc66-10 test-mc66-11 test-mc66-12
4307   test-mc66-13 test-mc66-14 test-mc66-15 test-mc66-16 test-mc66-17
4308   test-mc66-18 test-mc66-19 mc67 test-mc67-1 test-mc67-2 test-mc67-3
4309   test-mc67-4 test-mc67-5 test-mc67-6 test-mc67-7 test-mc67-8
4310   test-mc67-9 test-mc67-10 test-mc67-11 test-mc67-12 test-mc67-13
4311   test-mc67-14 test-mc67-15 test-mc67-16 test-mc67-17 test-mc67-18
4312   test-mc67-19 mc68 test-mc68-1 test-mc68-2 test-mc68-3 test-mc68-4
4313   test-mc68-5 test-mc68-6 mc69 test-mc69-1 test-mc69-2 test-mc69-3
4314   test-mc69-4 test-mc69-5 test-mc69-6 test-mc69-7 test-mc69-8
4315   test-mc69-9 test-mc69-10 test-mc69-11 test-mc69-12 test-mc69-13
4316   test-mc69-14 test-mc69-15 test-mc69-16 test-mc69-17 test-mc69-18
4317   test-mc69-19 mc70 test-mc70-1 test-mc70-2 test-mc70-3 test-mc70-4
4318   test-mc70-5 test-mc70-6 test-mc70-7 test-mc70-8 test-mc70-9
4319   test-mc70-10 test-mc70-11 test-mc70-12 test-mc70-13 test-mc70-14
4320   test-mc70-15 test-mc70-16 test-mc70-17 test-mc70-18 test-mc70-19 mc71
4321   test-mc71-1 test-mc71-2 test-mc71-3 test-mc71-4 test-mc71-5
4322   test-mc71-6 test-mc71-7 mc72 test-mc72-1 test-mc72-2 test-mc72-3
4323   test-mc72-4 test-mc72-5 test-mc72-6 prompt-for-new-values
4324   add-method-restarts convert-effective-method standard-with-restarts
4325   testgf16 testclass16a testclass16b testclass16c testclass16d
4326   user-method def-user-method test-um01 test-um02 test-um03 test-um04
4327   test-um05 test-um06 test-um07 test-um08 test-um10 test-um11 test-um12
4328   test-um13 foo128 foo129 *foo129-counter* foo130 *foo130-counter*
4329   foo131 foo131a foo131b foo132 foo132a foo132b incomplete147
4330   mixin-foo-144 class-foo-144 fun-144 class-bar-144 mixin-foo-145
4331   class-foo-145 fun-145 class-bar-145 foo146 foo147 foosub147 foo148))
4332()
4333