home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / lisp / lispnews / text0219.txt < prev    next >
Encoding:
Text File  |  1985-11-10  |  3.6 KB  |  97 lines

  1.     The following test demonstrates a problem with flavors.l as it is
  2. distributed with Release 38.91.  (The "a" after the minor number indicates a
  3. couple of changes made locally - mostly involving preloading struct, loop and
  4. such.  flavors.l wasn't touched.)
  5.  
  6.     The problem is that simple method combination doesn't work for trivial
  7. reasons.  A fix is suggested below.  As the example shows, the combined method
  8. for :PROGN combination is wrong. (:OR, :LIST ... all have the same problem).
  9.  
  10. Franz Lisp, Opus 38.91a (with Zetalisp compatability package)
  11. -> (defflavor object
  12.      (color)
  13.      ()
  14.      :gettable-instance-variables
  15.      :settable-instance-variables
  16.      :initable-instance-variables
  17.      (:method-combination (:progn :base-flavor-last :test1)))
  18. object
  19. -> (defmethod (object :test1) ()
  20.      (format t "~&object :test1~%"))
  21. (:method object :test1)
  22. -> (defflavor car
  23.      (price)
  24.      (object)
  25.      :gettable-instance-variables
  26.      :settable-instance-variables
  27.      :initable-instance-variables)
  28. car
  29. -> (defmethod (car :test1) ()
  30.      (format t "~&car :test1~%"))
  31. (:method car :test1)
  32. -> (setq car (make-instance 'car))
  33. #<car 591928>
  34. -> (send car ':test1)
  35. |Error:| eval: Undefined function  :progn
  36. <1>: (debug)
  37.  
  38. <------debug------>
  39.  
  40. :bk
  41.  
  42. <------debug------>   <--- you are here
  43. (eval (debug))
  44. (break-err-handler (|ER%undef| 0 t |eval: Undefined function | :progn))
  45. (:progn (lexpr-funcall (function car-test1-method) .daemon-caller-args.) (lexpr-funcall (function object-test1-method) .daemon-caller-args.))
  46. ((lambda (.daemon-caller-args.) .daemon-caller-args. (:progn (lexpr-funcall (function car-test1-method) .daemon-caller-args.) (lexpr-funcall (function object-test1-method) .daemon-caller-args.))) (do ((g00005 g00004 (|1-| g00005)) (g00006 () (cons (arg g00005) g00006))) ((< g00005 1) g00006)))
  47. ,
  48. ,
  49. ,
  50. (send car (quote :test1))
  51. (eval (send car (quote :test1)))
  52. <bottom of stack>
  53.  
  54.     Look at the combined method:
  55.  
  56. (:progn
  57.      (lexpr-funcall (function car-test1-method) .daemon-caller-args.)
  58.      (lexpr-funcall (function object-test1-method) .daemon-caller-args.))
  59.  
  60.     I think the problem is caused by the fact that in the older package system,
  61. the keyword package inherited from the global package.  Thus :PROGN (in the
  62. keyword package) was the same atom as PROGN (in global).  However, this isn't
  63. true in Franz.  :PROGN isn't EQ to PROGN, and it shouldn't be.  (The same
  64. problem occurs for all of the other simple method combination types too, e.g.
  65. :OR, :LIST ...).  One possible fix is to add an alist
  66. (SIMPLE-METHOD-COMBINATION-TYPE-ALIST) to store the correspondence between
  67. :PROGN and PROGN, like so:  (I just tested this code locally and it seemed to
  68. work.)
  69.  
  70. #+franz
  71. (DEFCONST SIMPLE-METHOD-COMBINATION-TYPE-ALIST
  72.         '((:PROGN . PROGN)
  73.           (:AND . AND)
  74.           (:OR . OR)
  75.           (:MAX . MAX)
  76.           (:MIN . MIN)
  77.           (:+ . +)
  78.           (:APPEND . APPEND)
  79.           (:NCONC . NCONC)))
  80.  
  81. (DEFUN SIMPLE-METHOD-COMBINATION (FL MAGIC-LIST-ENTRY)
  82.   (LET ((METHODS (GET-CERTAIN-METHODS MAGIC-LIST-ENTRY NIL NIL NIL NIL))
  83.     (WRAPPERS-P (SPECIALLY-COMBINED-METHODS-PRESENT MAGIC-LIST-ENTRY)))
  84.     (OR (AND (NOT WRAPPERS-P) (NULL (CDR METHODS)) (CAR METHODS))
  85.     (HAVE-COMBINED-METHOD FL MAGIC-LIST-ENTRY)
  86.     (MAKE-COMBINED-METHOD FL MAGIC-LIST-ENTRY
  87.            ;; In the old package system, :progn maps to progn trivially
  88.            ;; via package inheritance (keyword inherits from global).
  89.            ;; In Franz, we use an alist to implement the mapping.
  90.        (CONS #-franz (CADR MAGIC-LIST-ENTRY)
  91.                  #+franz (CDR (ASSQ (CADR MAGIC-LIST-ENTRY) 
  92.                                  SIMPLE-METHOD-COMBINATION-TYPE-ALIST))
  93.                  (MAPCAR 'METHOD-CALL
  94.                      METHODS))))))
  95.  
  96.  
  97.