Hi Johan: our main goal is to simplify evolution of software by making it partially automatic. Finding good ways to organize the compilation process helps to improve the efficiency of the tools involved in automating the evolution. I think I understand your point below. What is a little surprising is that we are good at supporting CCG and ICG evolution yet below you consider the case where the ICG changes rarely. -- Karl >From johan@ccs.neu.edu Mon Jul 6 19:07:36 1998 >To: johan@ccs.neu.edu, boaz@ccs.neu.edu, dougo@ccs.neu.edu, > jayantha@ccs.neu.edu, mira@ccs.neu.edu, lieber@ccs.neu.edu >Subject: Modifying the Traversal compilation alg >From: Johan Ovlinger > >I tried to send this off during the weekend, but I think that the >power outage nixxed it. > >In summarium, I argue that we need to change our compilation >algorithm slightly, in order to satisfy the property that everytime a >traversal changes in an APPC, the CCG must not be recompiled. > >The difficulty is; where to put the code generated for a class in the >ICG. I have toyed with letting the "classes" of the ICG be real >classes, but this gets me into trouble everytime. So until someone can >come up with a workable suggestion to the contrary, I'll assume that >the "classes" of the ICG are infact interfaces. > >It is probably unavoidable (at least in the beginning) that _some_ >code must be put in the CCG. notably, if class A' in the ICG is mapped >(via the Name Map) to class A in the CCG, then all the getters and >setters of A' must go in A. However, if we assume that the ICG changes >seldomly, but that the traversals in an APPC change often, then at >least we only have to recomplie the whole she-bang once in a while. >\footnote{I have a workable solution so that the CCG never needs to be >recompiled, but it is quite rickety, and probably not worth looking at >for a while.} > >The brunt of the modification I propose is that instead of traversal >methods being scattered around the CCG, but them in one class >instead. The calling interface now becomes compatible with >TAO. Perhaps an example would be best: > >Imagine a CCG: > >A = B. >B : C. >C = . > >A { traversal foo(Visitor V) { to *; } > >Generates currently > >class A { > B b; > B get_b() { return b;} > foo(Visitor v) { > v.before(this); > get_b().foo(v); > v.after(this); > } >} > >class B { > abstract foo(Visitor v); >} > >class C { > foo(Visitor v) { > v.before((B) this); > v.before(this); > v.after(this); > v.after((B) this); > } >} > > >And in my scheme would generate > >class A { > B b; > B get_b() { return b;} >} > >class B { > C get_c() { (this instanceof C) return (C) this; else return null; } >} > >class foo > foo_A(A host, Visitor v) { > v.before(host); > foo_B(host.get_b(),v); > v.after(host); > } > foo_B(B host, Visitor v) { > v.before(host); > foo_C(host.get_c(),v); > v.after(host); > } > foo_C(C host, Visitor v) { > v.before(host); > v.after(host); > } >} > >Notice how the subclass edge is treated just like an optional normal >edge. Also notice how the expected type of the host is encoded in the >name. > >Advantages: >1) >By not relying on java's dispatch rules, we allow ICGs to conform to a >larger set of CCGs, notably those that have a different inheritance >structure. > >An example. The CG above is the ICG, and the CCG is > >S = T. >T : V. >V = W. >W =. > >Now map A = S, B = T, C = W. > >Notice that C is now not a subclass of B. Relying on java's dispatch >rules would be not good. However, by having getters for the subclass >edge and by encoding the expected type of the host in the method name, >the day is saved. Hurray! > >2) >Only the traversal class needs to be recompiled in case of a >modification. > > > >Johan > >