Hi Doug: sorry for not responding to your point. I like your principle of least surprise and according to that we should make it easy for people who have read about the Visitor design pattern in GOF. They expect overriding inheritance between visitor methods as you show in the example below: > CostVisitor : DiscountVisitor *common* int. > > CostVisitor { > before Dessert (@ c = 3; @) > before Mousse (@ c += 4; @) > } > DiscountVisitor { > // Mousse and Cake are half off. > before Mousse (@ c += 2; @) Doug writes about overriding inheritance (in previous message): >Currently, it simply prints "conc", i.e. overriding behavior. In >order to have the Abs wrapper be called, you have to do this: > > Conc { before Foo (@ super.before(host); System.out.println("conc"); @) } > >However, this makes some assumptions about how wrappers are translated >to ordinary Java methods, which shouldn't be exposed. (The >translation is less straightforward when it involves edge wrappers, >especially around methods, and in any case may change in future >versions.) I don't think this to be a big problem with overriding inheritance. But you make an important point. The question is how likely it is that what is exposed will change. Overall, I like the overriding approach for visitor methods. -- Karl >From dougo@ccs.neu.edu Sat Jun 7 21:10:15 1997 >From: Doug Orleans >MIME-Version: 1.0 >Cc: binoy@ccs.neu.edu, fox@ccs.neu.edu, ghulten@ccs.neu.edu, > jayantha@ccs.neu.edu, johan@ccs.neu.edu, kedar@ccs.neu.edu, > lth@ccs.neu.edu, dougo@vega.ccs.neu.edu >Subject: Re: incremental inheritance > >Karl Lieberherr writes: > > >What should be the behavior in the following case? > > > > > > foo.cd: > > > Foo = . > > > Abs : Conc. > > > Conc = . > > > > > > foo.beh: > > > Abs { before Foo (@ System.out.println("abs"); @) } > > > Conc { before Foo (@ System.out.println("conc"); @) } > > > Foo { > > > traversal t(Abs v) { to Foo; } > > > (@ > > > public static void main(String args[]) { > > > new Foo().t(new Conc()); > > > } > > > @) > > > } > > > > > >Currently, it simply prints "conc", i.e. overriding behavior. In > > >order to have the Abs wrapper be called, you have to do this: > > > > > > Conc { before Foo (@ super.before(host); System.out.println("conc"); @) } > > > > We went through those decisions as part of the design of propagation > > patterns. Cun, Nacho and I were for incremental inheritance > > of wrappers and later Linda and Walter proposed overriding inheritance. > > We used overriding inheritance for a while in Demeter/C++. It did not > > work well; Cun then implemented incremental inheritance which > > worked very well. > >I think the above case is different from what you are referring to. >It involves inheritance of visitor classes, not inheritance in the >object structure that is being traversed (which I agree should >definitely use incremental inheritance). This is a different axis, >and I don't think the answer is quite as clear (the two people who >responded to my question the first time gave opposite answers). > > > Here is my current view (see the Meal example, page 260 of my book on AP): > > > > Suppose you have a meal class graph and you want to compute the cost of a meal: > > With incremental inheritance it is easy to define the costs > > inrementally as shown on page 260. Such simple problems > > should have simple solutions and incremental inheritance provides > > this. > >In Demeter/Java, this translates to: > > dessert.cd: > Dessert : Mousse | Cake. > Mousse = [ WhippedCream ]. > Cake = . > CostVisitor = int. > > dessert.beh: > CostVisitor { > before Dessert (@ c = 3; @) > before Mousse (@ c += 4; @) > before Cake (@ c += 2; @) > before WhippedCream (@ c += 1; @) > after Dessert (@ System.out.println(" dessert cost " + c); @) > } > >And this works as intended. What I'm asking about is something like: > > CostVisitor : DiscountVisitor *common* int. > > CostVisitor { > before Dessert (@ c = 3; @) > before Mousse (@ c += 4; @) > before Cake (@ c += 2; @) > before WhippedCream (@ c += 1; @) > after Dessert (@ System.out.println(" dessert cost " + c); @) > } > DiscountVisitor { > // Mousse and Cake are half off. > before Mousse (@ c += 2; @) > before Cake (@ c += 1; @) > // WhippedCream is free. > before WhippedCream (@ @) > after Dessert (@ System.out.println(" discount dessert cost " + c); @) > } > >This works with overriding inheritance of visitors; with incremental >inheritance, you'd have to subtract instead of add, and both costs >would be printed-- it would probably require making sibling visitor >classes, rather than parent/child. > >I guess it doesn't make too much difference which way it works out, >since the user can get the right behavior by rearranging the visitor >hierarchy in most cases (which is probably more flexible than the >class structure hierarchy). But it would be nice to use what would >best comply with the "principle of least surprise", and I still >haven't decided what that is... > >--Doug >