[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: defmethod lambda list bug



Rick Taube <hkt@zkm.de> writes:

> theres a bug in clisp's defmethod that doesn't allow both optional  
> and keyword arguments to be supplied in a calling form.

Yes. Please patch clos.lsp:

*** clos.lsp.orig       Mon Jan  3 03:40:20 1994
--- clos.lsp    Mon May  2 18:07:07 1994
***************
*** 2493,2500 ****
           (apply-fun (if restp 'APPLY 'FUNCALL))
           (apply-args `(,@req-vars ,@(if restp `(,rest-var) '())))
           (lambdalist `(,@req-vars ,@(if restp `(&REST ,rest-var) '())))
           (key-vars '())
!          (lambdalist-with-key lambdalist)
           (arg-order (gf-argorder gf))
           (methods (gf-methods gf)))
      ; Determine the effective method:
--- 2493,2501 ----
           (apply-fun (if restp 'APPLY 'FUNCALL))
           (apply-args `(,@req-vars ,@(if restp `(,rest-var) '())))
           (lambdalist `(,@req-vars ,@(if restp `(&REST ,rest-var) '())))
+          (opt-vars '())
           (key-vars '())
!          (lambdalist-keypart '())
           (arg-order (gf-argorder gf))
           (methods (gf-methods gf)))
      ; Determine the effective method:
***************
*** 2532,2541 ****
                          (append (fourth signature) (mapcap #'fifth signatures))
                          :from-end t
                     )) )
                  (setq key-vars (n-gensyms (length keywords)))
!                 (setq lambdalist-with-key
!                       `(,@lambdalist
!                         &KEY
                          ,@(mapcar #'(lambda (kw var) `((,kw ,var)))
                                    keywords key-vars
                            )
--- 2533,2542 ----
                          (append (fourth signature) (mapcap #'fifth signatures))
                          :from-end t
                     )) )
+                 (setq opt-vars (n-gensyms (second signature)))
                  (setq key-vars (n-gensyms (length keywords)))
!                 (setq lambdalist-keypart
!                       `(&KEY
                          ,@(mapcar #'(lambda (kw var) `((,kw ,var)))
                                    keywords key-vars
                            )
***************
*** 2617,2627 ****
          (let* ((ef-form (ef-1 primary-methods before-methods after-methods around-methods))
                 (ef-fun (if (and (eq (car ef-form) apply-fun)
                                  (equal (cddr ef-form) apply-args)
!                                 (equal lambdalist lambdalist-with-key)
                             )
                           (cadr ef-form)
!                          `#'(LAMBDA ,lambdalist-with-key
!                               ,@(if key-vars `((DECLARE (IGNORE ,@key-vars))))
                                ,ef-form
                              )
                ))       )
--- 2618,2638 ----
          (let* ((ef-form (ef-1 primary-methods before-methods after-methods around-methods))
                 (ef-fun (if (and (eq (car ef-form) apply-fun)
                                  (equal (cddr ef-form) apply-args)
!                                 (null lambdalist-keypart)
                             )
                           (cadr ef-form)
!                          `#'(LAMBDA
!                               ,@(if (null opt-vars)
!                                   `(,(append lambdalist lambdalist-keypart)
!                                     ,@(if key-vars `((DECLARE (IGNORE ,@key-vars))))
!                                    )
!                                   `(,lambdalist
!                                     (APPLY #'(LAMBDA (&OPTIONAL ,@opt-vars ,@lambdalist-keypart)
!                                                (DECLARE (IGNORE ,@opt-vars ,@key-vars))
!                                              )
!                                            ,rest-var
!                                    ))
!                                 )
                                ,ef-form
                              )
                ))       )


To regenerate lispinit.mem without rebuilding clisp from scratch:
"clisp -c clos", "clisp -i clos -x '(saveinitmem)'" won't work.
You have to set up a file closfix.lsp which contains the line
(in-package "CLOS")
and the definition of compute-effective-method
from the fixed clos.lsp and use this instead:
"clisp -c closfix", "clisp -i closfix -x '(saveinitmem)'"


                    Bruno Haible
                    haible@ma2s2.mathematik.uni-karlsruhe.de