Transcript function

1
Functional Visitor
 Initially proposed by Shriram Krishnamurthi @
Brown University
 Motivation Example
Container checking -- Make sure each Container
is not overloaded
*
contains
Item
+ int total( )
Container
+ int total( )
+ void check()
capacity
Capacity
Simple
w
Weight
2

Motivation Example
 Typical Object-oriented Implementation
abstract class Item {
int total() {return getWeight().getValue();}
}
class Simple extends Item {
}
class Container extends Item {
Vector contains;
int total() {
int t=0;
//for each element of the Vector, call total(), then sum
// toghether to t;
return t;
}
void check() {
if(getCapacity()< this.total())
System.out.println(“oveerloaded”);
//for each element of the Vector, if instanceof(Container)
// call check() on it.
}
}
3

Motivation Example
 How about Adaptive implementation (by DJ)
DifferenceVisitorDJ {
{{
// stack handling
public void start() { stack = new Stack(); }
public void before(Container o) {
stack.push(sV.getReturnValue()); }
public void after(Container o) {
difference = ((Integer) sV.getReturnValue()).intValue() ((Integer) stack.pop()).intValue(); }
public Object getReturnValue() {return new Integer(difference);}
}}
}
 Using side effect, lose the power of recursive
computation and combinability provided by
recursive function
4

Motivation Example
 But we do want the structure-shy feature of
Adaptive programming, i.e. DJ.
 Why not let the Visitor have access to the
return value of its sub traversals, so that we
can simulate the functional programming style
in Visitor?
 It implies we have to all Visitor methods having
return value.
5

Interface of Functional Visitor
 Three classes:
 FuntionVisitor, FuntionalOGS, Subtraversal
 In a subclass of FunctionVisitor, you can define
method like:
Object around(SomeClass h,Subtraversal st);
Object combine(Object[] values);
 The semantics (informal) of the around method
is as follows: when the traversal reaches an
object whose type matches SomeClass , the
return value of the traversal on this object is
determined by the return value of this around
method. The return value is available to its
parent object for further combination. The
Subtraversal class is provided by the run time
library and the object will be passed to the
around method automatically at run time.
6

Interface of Functional Visitor
 In the body of the Object around(SomeClass
h,Subtraversal st), you can control how the sub
traversals will going and access the return
values of the sub traversals, by one of the
following four ways:
Object apply(String label)
Object[] applySuper()
Object[] applyElements(String label)
Object[] apply()
 In your around method, you have the complete
control of the traversal
 If you don't define around method on a class,
then the default combine semantics will be
applied automatically to the array of Object
which get from each of the edges from the class.
The way you want to combine is specified as
Object combine(Object[] values).
7

Interface of Functional Visitor
 It is backward-compatible with the default DJ
package, i.e., if you don't define any around or
combine method in a visitor class, then it will
behave just the same as an ordinary DJ visitor
8

Container Example implemented by Function
Visitor
class Main {
static public void main(String args[]) throws Exception {
ClassGraph cg=new ClassGraph(true,false);
Container a = Container.parse(System.in);
TraversalGraph allWeights = new TraversalGraph(
"from Container bypassing -> *,tail,* to Weight",cg);
FunctionalOGS fogs=new FunctionalOGS(a,allWeights);
fogs.traverse(new DifferenceVisitorDJ());
}
}
9

Container Example implemented by Function
Visitor
class DifferenceVisitorDJ extends FunctionVisitor {
Object combine(Object[] values) {
int total=0;
for(int i=0; i<values.length; i++) {
if(values[i]!=null)
total+= ((Integer)values[i]).intValue();
}
return new Integer(total);
}
Object around(Weight w,Subtraversal st) {
return w.get_i();
}
Object around(Container c,Subtraversal st) {
Integer total = (Integer)st.apply("contents");
if(total.intValue() > c.get_capacity().get_i().intValue())
System.out.println(" A Overloaded Container");
return total;
}
}
10

Conclusion
 Functional Visitor combines the power of Adaptive
Programming and functional programming
 Users have more flexibilities to control the
traversal at run time
 Ironically, the functional style is implemented by
side effect.
 You will use it in a more complex situation, i.e., to
find unbound variables in a language struct.