Hi David: Your message has created a very positive echo in our team. Both Johan and Doug think you have a good idea which is worth putting into a paper. I agree too. Please note below that the second message corrects the first one. Johan would like to be working on the paper with you as he completes his other writing tasks. I am also very interested in this topic. Because you think this approach is very useful (might become main stream), it might be good to write the paper for practitioners and to plan for a publication in IEEE software. Both Doug and Johan had concerns regarding the speed of the system because of the use of reflection. Are you running on a fast JVM? If it is ok with you, I put our discussions into: http://www.ccs.neu.edu/research/demeter/related-work/novell for others to follow. -- Karl From johan@ccs.neu.edu Thu Aug 20 11:38:53 1998 cc: dougo@ccs.neu.edu, jayantha@ccs.neu.edu, johan@ccs.neu.edu, mira@informatik.uni-siegen.de Subject: Re: a better Demeter method Date: Thu, 20 Aug 1998 11:38:34 -0400 From: Johan Ovlinger Yes, it does sound alot like TAO. SIDE NOTE I was thinking that it will be nice when we finally get around to repackaging traversals in their own class, because if we do it well, there should be no difference between the use of static (compile time) and dynamic (TAO) traversals. That's be pretty funky. END NOTE Anyways, back to the email. David describes a number of concepts. I'll comment on each one separately. (1) Traversal object (A) A traversal object does the weaving at runtime. It takes an object to be traversed, a strategy for the traversal, and a visitor. The traverse() method loops: (a) hands the object to the strategy which returns the next subobject. (b) hands the subobject to the visitor. (c) if the subobject can be traversed itself, recurse into it. (B) Before and after traversing, it hands the traversal object itself to the visitor. I bake this into the classes. Each class is primed (my new terminology for a peice of 'add-once' code that enables a class of dynamic behavior) with code to traverse that class depending on the Traversal object (david call the traversal object a strategy object) (2) Strategy object (A)Strategy classes are more tightly coupled with their targets than I'd like; however, if the target object already uses a well-known containment (I've included strategies for enumeration and iterator trees) then strategies decoupled from their targets. In other words, unlike Demeter which is always structure-shy, this approach is sometimes structure-shy. (B)I invented my own interface instead of using a well-known one such as enumeration or iteration because I wanted the traversal to be intentional, not automatic. Suppose my target object implements enumeration, but that's not the order I want. This way I can write my own. If I change my mind and want enumeration order, then I just plug in the enumeration stategy. He says nothing about how the strategy is implemented. However, he seems very proud of his mapping (and I am very proud of mine to- it is a wonderful work of circular art). I suspect that he uses a representation close to mine. I don't understand any of A)) though. B) seems ok; we've discussed adding the ability to traverse enumerations before but we seem never to get around it. TAO is aimed at emulating demeter traversals, and thus didn't do this. (3) Vistor object (A) The vistors can have before(Traversal host) and after(Traversal host) methods. See 1B above. I prefer these instead of constructor/destructors(finalize()) because Java only does destruction during garbage collection. (B) The abstract Visitor object uses reflection to avoid changing its code. before(Visitor v, Object host) invokes v.before([correct class] host) if it exists. If it doesn't exist, just return. A) is the start/finish methods of demjava I think. B) TAO uses no reflection (and is plenty slow anyway). Instead, all visitors that can be used with TAO must subclass Visitor. Visitor has empty methods for all classes, thus guaranteeing that all wrappers will work. I'm not worried about the speed cost of all those method sends, as demjava's compile time traversals pay the same cost when using the same visitors, and are much faster. Thus the slowdown is elsewhere. (4) Filtering Filtering can be done in the object itself, the strategy, or the visitor. I think DemJava can selectively prune out sections of the graph easier. This seems to be data-driven traversals. TAO is able to use Around methods. Oh, I lied earlier. Around methods use reflection. I can't recall, but I think as much reflection as possible is done statically. Around methods are probably the major factor slowing TAO down. I am really looking for a good excuse to dust off TAO and resync it with demjava. It has fallen behind, and its generated code no longer compiles :-( David seems to have independently reinvented TAO. I'd be intertested to see how he represents strategies, most notably those with interesting things done to inheritance towers. That gave me alot of trouble. Johan From johan@ccs.neu.edu Thu Aug 20 12:07:38 1998 To: Karl Lieberherr cc: dougo@ccs.neu.edu, jayantha@ccs.neu.edu, johan@ccs.neu.edu, mira@informatik.uni-siegen.de Subject: Re: a better Demeter method Date: Thu, 20 Aug 1998 12:07:33 -0400 From: Johan Ovlinger I just had a look at the code, and want to correct some of what I said earlier. David is dynamic in a different way than TAO. You could argue that TAO is a highly optimised subset of David's stuff. David's stuff also works with compile time traversals. On the other hand, I get the feeling that it will be slower than both demeter and TAO. David's main contribution is that he gives all strategies the same signature regardless of whether they are compile time or dynamic. In the ealier mail, I was musing that this would be cool if we did it with TAO and demeter. Any class that implements the Strategy interface must be able to produce a list of traversabel parts from any given object. This is very flexible. Any class that implements the interface can be used as a strategy- perhaps one produced at compile time from a succint path description, or a class that takes a path description in its constructor. Strategies are thus an easy way to implement data driven traversals. This is a cool idea. You could spend some time thinking about cool DSLs that specify traversals. The difference between TAO and davids stuff is that TAO is more advanced in the kinds of visits you can have (around, before, after) (I still haven't added edge wrappers, but that should be easy), but has a quite rigid path desription language. David's stuff allows more dynamic traversals, but is quite restrictive on what visits can be performed. Also, The user needs to write much more code to implement any traversal. (of course, once you've written a runtime traversal class, you can reuse it). Another way