Thread: [cedet-eieio] call-next-method invocation order
Brought to you by:
zappo
From: Frank <som...@gm...> - 2010-07-18 20:15:23
|
Hi there, I'm not sure maybe there's a problem with (call-next-method)'s invocation order with multiple inheritance; Check this tree out +--base +--derived1 | +--derived2 | +--derived3 +--derivedX +--derived3 And here's the code for it; Well it's kinda a complex example but the point why I bother you guys with it is if I run this example on Allegro CL I get a different result; BTW if I add :method-invocation-order :depth-first to class derived2 I get the same result as on Allegro CL; As I'm not an expert in CL I'll leave it up to you guys what to do with it; Thanks Frank (require 'cl) (require 'eieio) (defclass base () ()) (defmethod func ((this base)) (foo this)) (defmethod foo ((this base)) (message "base::foo")) (defclass derivedX (base) ()) (defclass derived1 (base) ()) (defmethod foo ((this derived1)) (message "derived1::foo")) (defclass derived2 (derived1) () ;;; :method-invocation-order :depth-first ) (defmethod foo ((this derived2)) (call-next-method) (message "derived2::foo")) (defclass derived3 (derived2 derivedX) ()) (setq td1 (make-instance 'derived2)) (func td1) ;; Results in: ;; derived1::foo ;; derived2::foo ;;XXX shouldn't the result be the same as in the former example? ;;XXX on Allegro CL the result is the same as for td1 (setq td2 (make-instance 'derived3)) (func td2) ;; Results in: ;; base::foo ;; derived2::foo |
From: Jan M. <jan...@un...> - 2010-07-19 01:07:45
|
Hi Frank. > I'm not sure maybe there's a problem with (call-next-method)'s > invocation order with multiple inheritance; > > Check this tree out > > +--base > +--derived1 > | +--derived2 > | +--derived3 > +--derivedX > +--derived3 > > And here's the code for it; > Well it's kinda a complex example but the point why I bother you guys > with it is if I run this example on Allegro CL I get a different result; > BTW if I add :method-invocation-order :depth-first to class derived2 I > get the same result as on Allegro CL; EIEIO has three linearization methods: depth-first, breadth-first and c3 (see [1]). The default is breadth-first search which can reach base before derived1, as your td2 example shows, since paths from derived3 have length 2 in both cases. The method used in CLOS (and therefore probably in Allegro CL) is different from all three and also described in [1]. In many cases, even complex hierarchies, the c3 linearization mentioned in [1] does the right thing. Your example should work with c3 linearization. It can be used in EIEIO with :method-invocation-order :c3. > As I'm not an expert in CL I'll leave it up to you guys what to do with it; Maybe the documentation can be improved. Kind regards, Jan [1] http://192.220.96.201/dylan/linearization-oopsla96.html |
From: Eric M. L. <er...@si...> - 2010-07-19 02:15:28
|
On 07/18/2010 07:16 PM, Jan Moringen wrote: >> Well it's kinda a complex example but the point why I bother you guys >> with it is if I run this example on Allegro CL I get a different result; >> BTW if I add :method-invocation-order :depth-first to class derived2 I >> get the same result as on Allegro CL; > > EIEIO has three linearization methods: depth-first, breadth-first and c3 > (see [1]). The default is breadth-first search which can reach base > before derived1, as your td2 example shows, since paths from derived3 > have length 2 in both cases. The method used in CLOS (and therefore > probably in Allegro CL) is different from all three and also described > in [1]. > > In many cases, even complex hierarchies, the c3 linearization mentioned > in [1] does the right thing. Your example should work with c3 > linearization. It can be used in EIEIO > with :method-invocation-order :c3. > >> As I'm not an expert in CL I'll leave it up to you guys what to do with it; > > Maybe the documentation can be improved. I was re-writing bits of the doc today based on the first question when I noticed that :c3 wasn't there. Then I noticed the doc didn't say what the default was. So I tried making :c3 the default (thus solving some of these issues from happening by default) and found that CEDET didn't build properly. (Complaints of malformed hierarchies.) Things then stalled for me and I didn't have time to finish. If this is going to be a common issue, I'd like to try and get this new mechanism in as the default, but it may take a while. Eric |
From: Frank <som...@gm...> - 2010-07-19 03:13:55
|
Eric M. Ludlam schrieb: > On 07/18/2010 07:16 PM, Jan Moringen wrote: > >>> Well it's kinda a complex example but the point why I bother you guys >>> with it is if I run this example on Allegro CL I get a different >>> result; >>> BTW if I add :method-invocation-order :depth-first to class derived2 I >>> get the same result as on Allegro CL; >> >> >> EIEIO has three linearization methods: depth-first, breadth-first and c3 >> (see [1]). The default is breadth-first search which can reach base >> before derived1, as your td2 example shows, since paths from derived3 >> have length 2 in both cases. The method used in CLOS (and therefore >> probably in Allegro CL) is different from all three and also described >> in [1]. >> >> In many cases, even complex hierarchies, the c3 linearization mentioned >> in [1] does the right thing. Your example should work with c3 >> linearization. It can be used in EIEIO >> with :method-invocation-order :c3. >> >>> As I'm not an expert in CL I'll leave it up to you guys what to do >>> with it; >> >> >> Maybe the documentation can be improved. > > > I was re-writing bits of the doc today based on the first question > when I noticed that :c3 wasn't there. Then I noticed the doc didn't > say what the default was. > > So I tried making :c3 the default (thus solving some of these issues > from happening by default) and found that CEDET didn't build properly. > (Complaints of malformed hierarchies.) > > Things then stalled for me and I didn't have time to finish. If this > is going to be a common issue, I'd like to try and get this new > mechanism in as the default, but it may take a while. > > Eric Fair enough!! BTW c3 doesn't seem to be available in emacs 23.2.1 Well I still puzzle how to apply the class option :method-invocation-order properly. (1) Does it have to be defined for all classes in a tree; (2) or to the base class and the specified invocation order is then effective for all child classes which inherit from it (3) or to the some class and if an object of this class is created then the specified invocation order is effective as specified by this class? Thanks Frank |
From: Jan M. <jan...@un...> - 2010-07-19 04:56:28
|
Hi Frank. > Fair enough!! > BTW c3 doesn't seem to be available in emacs 23.2.1 If you just wish to experiment, you could download eieio.el of the CEDET CVS version and load it into your current session. > Well I still puzzle how to apply the class option > :method-invocation-order properly. > > (1) Does it have to be defined for all classes in a tree; > > (2) or to the base class and the specified invocation order is then > effective for all child classes which inherit from it > > (3) or to the some class and if an object of this class is created then > the specified invocation order is effective as specified by this class? The method invocation order is determined by the class precedence list. When computing the class precedence list, the "starting point" class of the search process determines how the search process is carried out. In the context of invoking methods, the most specific class would be the "starting point". For MOP-based systems (unlike EIEIO) this means that the class-precedence-list method of the "starting point" class is called. In this case, that method (I make a slight simplification here) decides how the class precedence list is computed. In EIEIO, the class precedence list is also present and is computed based on the method-invocation-order of the "starting point" class. It is used in method invocation, together with other mechanisms. As a consequence of these other mechanisms, the method-invocation-orders of superclasses of the "starting point" class can influence method invocation. This behavior is not optimal (that's my impression), but it would required *a lot* of work to change it. Conclusion: In principle, only the "starting point" class matters. In today's EIEIO, superclasses may matter as well. Kind regards, Jan |