Hi Mira: your model and syntax look elegant. Seems to fit well into Demeter/Java. I hope we can keep it this way. You write something like: CompleteCheckingVisitor(Strategy s1) = CheckingVisitor(s1, get_capacity) modifies InitialVisitor(s1) modifies SummingVisitor(s1, value);} s1 = from Container to Weight; Container{ int check() { CompleteCheckingVisitor(s1)} we could also define: CompleteCheckingVisitor2(Strategy s1) = CheckingVisitor(s1, get_capacity) modifies InitialVisitor(s1) modifies CountingVisitor(s1);} Container{ int check2() { CompleteCheckingVisitor2(s1)} provided CountingVisitor also returns an integer. How does the "return from next visitor approach" work when we have two next visitors, as in the average example. -- Karl From mira@ccs.neu.edu Mon Dec 1 19:11:29 1997 Subject: the structure of a visitor definition To: lieber@ccs.neu.edu (Karl Lieberherr) Date: Mon, 1 Dec 1997 19:11:27 -0500 (EST) Cc: dougo@ccs.neu.edu (Doug Orleans), johan@ccs.neu.edu (Johan Ovlinger) Hi, I am sending you my way of organizing the definition of a visitor definition which is slightly different from that presented by Karl. Feedback is welcome. Thanks. -- Mira ------------------------ cut here ------------------------------------ generic_modifier_visitor(Strategy s, Method m1, ..., Method mk) { // variables that are global for a whole traversal are declared here init() {// code for initializing the declared traversal variables}; s.source { // here the modification at the source of the strategy is defined // variables that temporarily extend the object(s) // of the source class during the traversal are declared here init() {// code for initializing the variables declared to extend source objects }; change // what to do when getting at a source object is implemented here // I also think the name is not nice. Suggestions? Should we call // when-visiting? (@ ... this.m1 // some method from the basic functionality of the host (this) is // invoked here. By passing the name of the method as a parameter // we leave open which concrete method we are going to use ... [if some condition then] next(); // [] means optional. We could put a condition // on whether we traverse further at this place // next invokes the next implementation for the // method denoted by "change" to perform // either the next visiting task attached // to the traversal denoted by "change" // or the reamainder of the traversal itself // if no other visitor. Equivalent to saying "next.change" ... next.return ... // the result of the next visitor is invoked // for using the functionality // implemented in the "next" visitor. // The next visitor is the one a // generic_modifier modifies -- to // be bound by the modifies statement this.local_method_X(); // local_method_X() may be a // new method implemented by // this visitor } // end of "change" for s.source ... s.target { ... } // new methods implemented by the visitor, which may be used by the change parts of // this visitor if needed. local_method_1() { ... }; ... local_method_X() { ... }; return(...) // what this visitor provides to other visitors } // end of modifier-visitor -------- The concrete form of the visitors in the checking capacity example would be: SummingVisitor(Strategy s, Method f) { int total_sum; init (@ total_sum = 0; @) s.target { change (@ total_sum += this.f(); next(); @) } return (@ total_sum @) } InitialVisitor (Strategy s) { s.source { int initial; change (@ initial = next.return(); next(); @) return (@ next.return() - initial @) } } CheckingVisitor (Strategy s, Method f) { Violations violations; s.source { change (@ next(); if (next.return() > this.f()) { violations.number = new Integer(violations.number.intValue()+1); violations.places = violations.places.add(new ViolationItem(this, next.return)); } @) return (@ violations @) } Above violations are of the type Violations the structure of which is defined in the following class graph: Violations = Integer List. ViolationsItem = Container Integer. Than we could write: s1 = from Container to Weight; Container{ int check() { // at this place, we are saying that all pieces of code // in changes of all visitors are incrementally // contributing in the implementation of check() methods // in Container (the source of s1) and Weight // (the target of s1) respectively. CheckingVisitor(s1, get_capacity) modifies InitialVisitor(s1) modifies SummingVisitor(s1, value);} }