Hi Mira: a very useful mail I think. This brings us a big step further. >From mira@ccs.neu.edu Thu Oct 30 15:31:45 1997 >From: Mira Mezini >Subject: Re: same model >To: lieber@ccs.neu.edu (Karl Lieberherr) >Date: Thu, 30 Oct 1997 15:31:42 -0500 (EST) > >Hi Karl: > >> After a second thought, your proposal today matches the one below? >> Except that you don't view a context class as a class. > >It is clear that both models have similiraties, however they are not >the same. As I told you, the context relation and the Rondo >model share many things. However, there are two points to make >here: > >1. *** >------ > >There is a difference between the contex relation as described >in Linda's thesis (and TSE paper), and the current realization >of the realisation in Demeter/Java. The description is more general >than the current realization. Currently, context objects are I agree. >used only in combination with strategies to specify some behavior >that happens during traversing an object structure. This is also >reflected in the structure of context classes below: > >> Context classes should have the following structure: >> >> Context Class V { >> instance variables >> methods >> // several redefinitions: >> redefines C { // vertex based redefinition >> // additional instance variables >> D d; // not needed for attachment to objects >> // only for attachment to calls >> // overwrite or add new methods for C-objects >> f(A) {}; >> // incremental methods for C-objects >> before {}; >> after {}; >> around {}; >> // incremental methods for edges from C-objects >> before l {} >> after l {} >> around l {} >> // includes also "derived" edges (methods) >> before x(A) {} >> after x(A) {} >> around x(A) {} >> } >> redefines -> X,y,Y { // edge based redefinition >> // additional instance variables for source of edges >> // overwrite or add new methods for source of edges >> f(A) {}; >> // incremental methods for y-edge >> before {}; >> after {}; >> around {}; >> } >> >This structure subsumes the existence of before(), after() and >around() methods in the base class structure which is being modified, >right? These methods are actually present in all classes that are You are right. This generalization of context objects is geared towards traversals. >affected by a strategy (i.e. included in the computed strategy graph) >-- they are automatically generated by the >Demeter/Java preprocessor as empty methods which are called >by other methods whose implementation contains a strategy, right? right. >So, I totally agree with: > >> What is new here? >> >> DYNAMIC EXTENSION OF CLASS STRUCTURE for duration of a task. >> This removes the pollution of the class graph with information >> which is only needed for a specific task. > >But, what about modifying the behavior of classes whose behavior >definitions in the .beh files do not include strategies, i.e. >classes whose methods are simple Java code? >What about an account object which becomes dynamically >``saving''? There is no traversing involved here. Your examples >always involve traversing an object structure and iteratively >performing some task at each node. But. try to think in terms >of other examples. What about the distrubuted object which >at a certain moment because of some measurements of the network >resource availability shoud change its implementation? Certainly, we want to deal with that too. Often we want to change the implementation of a group of collaborating objects. But we don't want to commit to a detailed organization of the collaborating objects when we write the collaboration. > >> New parts and functions may only be used in redefinition. >> Either all incremental or all overrwriting. > >What does ``all incremental or all overrwriting'' mean? What is ``all''? >Could you explain this in more detail? > Let's see whether I can reconstruct what I said there. In Demeter/Java, when you add more visitors to a traversal, their methods are all incremental. Linda and Walter promoted an overriding model where methods at super classes override methods at subclasses. // Demeter/Java code // Manager a subclass of Employee int average() to {Salary, Employee, Manager} (Average, Count, Sum); at both Employee and Manager we have two before visitor methods and both will be called. in an overriding model only the one at Manager would be called. Mixing incremental and overrriding would be confusing. I think incremental is what we want. >2. *** >------ >The second point is as follows. Let us consider now the more general >description of the context relation (as described in Linda's >thesis or TSE paper), which is able to deal with both dynamic variations aka >strategy (or state) pattern and variations aka visitor pattern. >In this form the context relation is much more similar to the I agree. >Rondo style. Still, I have the impression that Rondo is slightly more general. >Let me explain why. > >Your contexts are objects, while my adjustments are classes (more >precisely class-like constructs). As a qonsequence, the dynamic >modification implied by the context relation results in a kind >of delegation-based style. Is that right? Here is some sample code from your >TSE paper implementing the example used for illustrating >the strategy pattern in GOF book: > > public class Composition{ > public void instance compose() {this.draw}; // <-- default implementation > public void draw() {...}; //some implementation > > ... > > public class TextCompositor { // Note this is a context class > ---------------------------- (*) > public void dosomething() {...} //some implementation > update class Composition { > void compose() {context.dosomething(); this.draw();} > --------------------- (**) > > ... > ... > > Composition c = new Composition() > TextCompositor t = new TextCompositor(); //create context object > --------------------- (***) > c::=t; > >(*) the structure of this context class as decribed here looks very different from the >structure of a context class as described above. There are no before and after methods >here. This is similar to Rondo's adjustments. That confirms my understanding. > >(**) (***) doSomething does something for the composition object ``c''. >Why should this method be sent to the context object? >This is a functionality the base object should now >additionally provide. We want to modify the behavior >of an existing object. What's the point of creating a new object here? >You would say: well, we need to encapsulate >somewhere the new state that TextCompositor may declare. >Definitely, but the new state is (a new) part of the existing >base object in the new situation (i.e. when >it uses a non-default strategy for composing). >That means the new state should be visible for the extended >functionality of the existing ``c'' object, but not >externally. It is ``c'' that now is (temporarily) ``biger'', >but there is no reason to create a new object. > I am not married to the context objects. I am ready to give them up for something better. > >It seems to me that: context attachement == bind the ``context'' identifier to >the cretated context object ''t''. >Than context.dosomething() is delegation, i.e. >``this'' should be implicitly passed along. > > >In Rondo this would look like: > > public class Composition{ > public void compose() {this.draw}; // <-- default implementation > public void draw() {...}; //some implementation > > adjustment TextCompositor { //Everything that is in a subclass can be put here > public void dosomething() {... this....} //some implementation. > //can refer to any method > // in the base class. > void compose() > {this.dosomething(); super.compose();} > //Note, ``this'' is a composition object > } modifies Composition when: #text. > > > ... > > > Composition c = new Composition(); > c.raise(#text); // Classes are attached here not objects. > --------------------------------------- > c.compose; > > ... //still text > > c.undo(#text); > > >At this point, let me summarize this long mail. >The integration of Rondo in Dem/J would mean: > >a) Realization of a more general dynamic behavior modification mechanism in >DEM/J, similar to the one intended by the context relation in its general >form, i.e. in addition to the restricted form currently implemented with the >context objects in DEM/J. This is similar to Rondo, but is missing in >the current implementation of DEM/J. Compared to context attachement, >Rondo applies modifications by class, rather than object attachments. > In Ian Holland's thesis he programs with contracts which are expressed in terms of objects (participants) and their obligations. Such a contract has also the flavor of an adjustment. Do you have more insight into the connection? Can we do with adjustments all we can do with contracts or is something missing. > >b) If we want to go further, adjustments could be used instead of >context objects even for traverse-based functionality. The name, >context or adjustment is not important, the point is rather at >the way structure and behavior are connected together. What I mean is >the following. Demeter/J compiler will as currently generate the >traversing code within a method whose implementation in >.beh file has a strategy specification. However, no empty before or >after methods needs to be inserted. >In this case, the .beh file would looks like: > > class Foo { > > method foo_1 { > strategy from X to Y} > } > > > adjustment Count { > method foo_1 { ... do something ...} > } > > > ... > > > Foo f = Foo new(){Count}; > f.foo_1; Foo { int count() to Y (Count); Count { (@ int total; @) init (@ total = 0; @) before Y (@ total++; @) return (@ total @) } Foo f = new Foo(); f.count(); still looks more natural to me. But let's follow what you say below: Foo { int count() to Y; } adjustment Count { (@ int total; @) init (@ total = 0; @) int count() { before Y (@ total++; super.count(); @) } return (@ total @) } Foo f = new Foo() with Count; f.count(); This looks not bad but we have the additional coupling with the function name. But that is handy in other situations. The strategy seems to be to get rid of attaching attachemnts to calls, but to only attach to objects. That is what contracts do. > >Disadvantage: - consistent naming of functions is important for adjustments to work. > >However, when looking at examples in the Demeter Homepages, e.g. in the >page titled "Demeter/Java: Adaptive Programming with traversals and visitors" >by Doug and you, one notices that also in context classes names of the >class or method which the context class modifies are stated explicitly. >When a context class modifies more that one method of >the class x, one should say which method in the base class a certain before >method modifies: > > > class Y { > > Y_M1 { > ... some traversal ... }; > > Y_M2 { > ... some traversal ... }; > } > > context class X { > .... > > updates Y { > > before Y_M1 {...}; > before Y_M2{...}; > > ...} >Is that right? yes, I checked this in the above example. > >That means, even with the before() and after() methods there are explicit >comittment in the code (in the form of class or method names) about >which context objects can be used with which classes. certainly. >Consider the piece of behavior from one of demeter/java pages >(http://www.ccs.neu.edu/research/demeter/posters/introDemeterJava/poster.html) > > >Computer { > traversal allEquip(PricingVisitor price, InventoryVisitor inv) { > bypassing -> CompositeEquipment,parts,* to Equipment; > } >} > >PricingVisitor { > before Equipment (@ total = total.add(host.get_netPrice()); @) > // Chassis are on sale... > before Chassis (@ total = total.add(host.get_discountPrice()); @) >} > >InventoryVisitor { > before Equipment (@ inventory.accumulate(host); @) >} > > >The PricingVisitor context can be only used as it is with a class >structure that has Equipment and Chassis. This cannot be avoided. >Nothing wrong about that. What I want to say, is that in one or th >other form you have some connecting points in the code, being >the names of the messages or classes. Yes. With adjustments we need to connect both with classes and method names? See count example, above. > >I guess, that's enough for one mail :-) Let us continue the discussion >in person or via forthcomming mails. > >-- Mira > > You express your ideas very clearly. -- Karl