Hi Doug and Lars: An interesting discussion we got ourselves into. I have made Lars' pages available from: http://www.ccs.neu.edu/research/demeter/DemeterJava/use/for-uguide/ I agree with Doug's examples how around methods should work. Will use them in my lecture. Is that ok Doug? My motivating example is: OnlyOnceVisitor {// prevent infinite loop around * (@ if (!host.get_visited()) { host.set_visited(true); subtraversal.apply(); } @) } trav(OnlyOnceVisitor, CountVisitor); OnlyOnceVisitor is a nice repair visitor which repairs lots of visitors which would otherwise get into an infinite loop on circular objects. -- Karl From dougo@ccs.neu.edu Tue Oct 7 07:29:40 1997 From: Doug Orleans To: Karl Lieberherr Cc: dem@ccs.neu.edu Subject: Re: semantics of around Karl Lieberherr writes: > Hi Doug and Binoy: > > /proj/adaptive/www/course/f97/hw/3/use-around > > Why is before of A executed if d is absent? > > What is the semantics of around when it is used in conjunction > with a second visitor? The currently implemented semantics are: Call all the befores of all the visitors, in the same order as the parameter list of the traversal method. Call the around method on the first visitor, which, when subtraversal.apply() is invoked, traverses the edges. Call all the afters of all the visitors, in reverse parameter list order. This is obviously broken (or is it obvious?), and I suspect it's even more broken when both visitors have around methods. And I don't even want to contemplate around methods on alternation/inheritance edges (at least not at this hour of the morning). I will see if I can quickly remedy this; the workaround (such as it is) is to only use one visitor if you want around methods to do the intuitive thing. (Or else change your intuition...) --Doug From lth@ccs.neu.edu Tue Oct 7 08:04:26 1997 To: Doug Orleans cc: Karl Lieberherr , dem@ccs.neu.edu Subject: Re: semantics of around From: Lars Thomas Hansen >The currently implemented semantics are: > > Call all the befores of all the visitors, in the same order as the > parameter list of the traversal method. > Call the around method on the first visitor, > which, when subtraversal.apply() is invoked, > traverses the edges. > Call all the afters of all the visitors, in reverse parameter list > order. > >This is obviously broken (or is it obvious?), and I suspect it's even >more broken when both visitors have around methods. Only a little broken :-) The specification for the semantics is on the project page for the around methods, .../home/lth/aao/impl.html. It specifies that around methods are nested in the traversal in left-to-right order, so if you have two visitors with around methods A1 and A2 (l-to-r), then A1 is called first and when A1 does subtraversal.apply(), then A2 is called, and when A2 does subtraversal.apply(), then the traversal continues. --lars From dougo@ccs.neu.edu Tue Oct 7 08:43:33 1997 From: Doug Orleans To: Lars Thomas Hansen Cc: Karl Lieberherr , dem@ccs.neu.edu Subject: Re: semantics of around Lars Thomas Hansen writes: > The specification for the semantics is on the project page for the > around methods, .../home/lth/aao/impl.html. It specifies that around > methods are nested in the traversal in left-to-right order, so if you > have two visitors with around methods A1 and A2 (l-to-r), then A1 is > called first and when A1 does subtraversal.apply(), then A2 is called, > and when A2 does subtraversal.apply(), then the traversal continues. Actually, your specification says: The around method is called after all before methods but it doesn't say whether "all before methods" includes those on other visitors in the traversal. The part about multiple visitors doesn't mention before methods at all. The question is: V1 { before X (@ 1 @) around X (@ 2; subtraversal.apply() @) } V2 { before X (@ 3 @) around X (@ 4; subtraversal.apply() @) } A { traversal t(V1, V2) { to Z; } } Does t execute 1 2 3 4, or 1 3 2 4? The current implementation is the latter, but I think it's fairly clear that it should be the former. More importantly, V1 { before X (@ 1 @) around X (@ 2; /* no apply */ @) } V2 { before X (@ 3 @) around X (@ 4; subtraversal.apply() @) } A { traversal t(V1, V2) { to Z; } } Does t execute 1 2, or 1 3 2? Again, the current implementation is the latter, but it should be the former. If you have a counter-argument for why the current implementation semantics should be kept, speak now or forever hold your peace. In any case, the implementation doesn't even do what you say about multiple visitors each with an around method (4 won't ever execute in the above example). I think I even have a comment in the source saying that this is broken. --Doug