home *** CD-ROM | disk | FTP | other *** search
- The following test demonstrates a problem with flavors.l as it is
- distributed with Release 38.91. (The "a" after the minor number indicates a
- couple of changes made locally - mostly involving preloading struct, loop and
- such. flavors.l wasn't touched.)
-
- The problem is that simple method combination doesn't work for trivial
- reasons. A fix is suggested below. As the example shows, the combined method
- for :PROGN combination is wrong. (:OR, :LIST ... all have the same problem).
-
- Franz Lisp, Opus 38.91a (with Zetalisp compatability package)
- -> (defflavor object
- (color)
- ()
- :gettable-instance-variables
- :settable-instance-variables
- :initable-instance-variables
- (:method-combination (:progn :base-flavor-last :test1)))
- object
- -> (defmethod (object :test1) ()
- (format t "~&object :test1~%"))
- (:method object :test1)
- -> (defflavor car
- (price)
- (object)
- :gettable-instance-variables
- :settable-instance-variables
- :initable-instance-variables)
- car
- -> (defmethod (car :test1) ()
- (format t "~&car :test1~%"))
- (:method car :test1)
- -> (setq car (make-instance 'car))
- #<car 591928>
- -> (send car ':test1)
- |Error:| eval: Undefined function :progn
- <1>: (debug)
-
- <------debug------>
-
- :bk
-
- <------debug------> <--- you are here
- (eval (debug))
- (break-err-handler (|ER%undef| 0 t |eval: Undefined function | :progn))
- (:progn (lexpr-funcall (function car-test1-method) .daemon-caller-args.) (lexpr-funcall (function object-test1-method) .daemon-caller-args.))
- ((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)))
- ,
- ,
- ,
- (send car (quote :test1))
- (eval (send car (quote :test1)))
- <bottom of stack>
-
- Look at the combined method:
-
- (:progn
- (lexpr-funcall (function car-test1-method) .daemon-caller-args.)
- (lexpr-funcall (function object-test1-method) .daemon-caller-args.))
-
- I think the problem is caused by the fact that in the older package system,
- the keyword package inherited from the global package. Thus :PROGN (in the
- keyword package) was the same atom as PROGN (in global). However, this isn't
- true in Franz. :PROGN isn't EQ to PROGN, and it shouldn't be. (The same
- problem occurs for all of the other simple method combination types too, e.g.
- :OR, :LIST ...). One possible fix is to add an alist
- (SIMPLE-METHOD-COMBINATION-TYPE-ALIST) to store the correspondence between
- :PROGN and PROGN, like so: (I just tested this code locally and it seemed to
- work.)
-
- #+franz
- (DEFCONST SIMPLE-METHOD-COMBINATION-TYPE-ALIST
- '((:PROGN . PROGN)
- (:AND . AND)
- (:OR . OR)
- (:MAX . MAX)
- (:MIN . MIN)
- (:+ . +)
- (:APPEND . APPEND)
- (:NCONC . NCONC)))
-
- (DEFUN SIMPLE-METHOD-COMBINATION (FL MAGIC-LIST-ENTRY)
- (LET ((METHODS (GET-CERTAIN-METHODS MAGIC-LIST-ENTRY NIL NIL NIL NIL))
- (WRAPPERS-P (SPECIALLY-COMBINED-METHODS-PRESENT MAGIC-LIST-ENTRY)))
- (OR (AND (NOT WRAPPERS-P) (NULL (CDR METHODS)) (CAR METHODS))
- (HAVE-COMBINED-METHOD FL MAGIC-LIST-ENTRY)
- (MAKE-COMBINED-METHOD FL MAGIC-LIST-ENTRY
- ;; In the old package system, :progn maps to progn trivially
- ;; via package inheritance (keyword inherits from global).
- ;; In Franz, we use an alist to implement the mapping.
- (CONS #-franz (CADR MAGIC-LIST-ENTRY)
- #+franz (CDR (ASSQ (CADR MAGIC-LIST-ENTRY)
- SIMPLE-METHOD-COMBINATION-TYPE-ALIST))
- (MAPCAR 'METHOD-CALL
- METHODS))))))
-
-
-