View
230
Download
1
Tags:
Embed Size (px)
Citation preview
Talk tonight
• Richard Stallman• Norton 112• 6:00 PM
SumVisitor exercise
• Assume you are given an LRS containing Integer objects (all non-null). Write a visitor which traverses the list structure and calculates the sum of all the int values.
• Ex: If the list contains Integers for 1, 2, 3, 4 and 5, the visitor must return an Integer containing 15.
SumVisitor exercise
• Done interactively, from scratch, in Eclipse.
• Final version in lrstruct.visitors package in SP10-CSE116-LRStruct project.
SumVisitor solutionpublic class SumVisitor implements IAlgo<Object,Integer,Integer> {
// The answer in the case of an empty list is zero// (because zero is the identity element of addition).public Integer emptyCase(LRStruct<Integer> host, Object _) {
return 0; }
// The answer in the case of a non-empty list is the sum of// the first item in the list and the sum of the rest of the // items in the list.public Integer nonEmptyCase(LRStruct<Integer> host, Object _) {
return host.getDatum() + host.getRest().execute(this, _);}
}
How do visitors work?
• This set of slides traces through the execution of a visitor we’ve seen before (the lengthVisitor) on a short list.
• It shows how the runtime stack makes recursion possible.
• First let’s recall:– how the visitor is defined– how ‘execute’ is defined in the two list state
classes
Length visitor
• in the empty case the answer is zero• in the non-empty case the answer is one more than
the length of the rest of the list
public Integer emptyCase(LRStruct<?> host, Object _){ return 0;}public Integer nonEmptyCase(LRStruct<?> host, Object _){
return 1 + host.getRest().execute(this,_);}
‘execute’ definition in states
• Empty state:
public Object execute(LRS host, IAlgo algo, Object argut){ return algo.emptyCase(host, input);}
• NonEmpty state:
public Object execute(LRS host, IAlgo algo, Object argut){ return algo.nonEmptyCase(host, input);}
Now let’s trace execution of the visitor
LRStruct<String> list = new LRStruct<String>();list.insertFront(“Wilma”).insertFront(“Fred”);LengthVisitor<String> visitor = new LengthVisitor<String>();int len = list.execute(visitor,null);System.out.println(“Length is ” + length);
Focus on the evaluation of:
list.execute(visitor,null)
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
space for return valuevisitor
arg (null)
this
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
space for return valuevisitor
arg (null)
this
Polymorphic
method call
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
arg (null)
this
this
algo
arg (null)
host
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
this
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
arg (null)
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
this
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
arg (null)
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
this
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
this
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
arg (null)
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
thisPolymorphic
method call
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
this
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
arg (null)
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
this
this
algo
arg (null)
host
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
this
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
arg (null)
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
this
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
this
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
arg (null)
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
this
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
this
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
this
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
arg (null)
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
this
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
this
Polymorphic
method call
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
this
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
arg (null)
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
this
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
this
this
algo
arg (null)
host
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
this
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
arg (null)
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
this
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
this
this
algo
arg (null)
host
0host
_ (null)
this
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
this
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
arg (null)
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
this
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
this
this
algo
arg (null)
host
0
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
this
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
arg (null)
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
this
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
this
0
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
this
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
arg (null)
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
this
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
0
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
this
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
arg (null)
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
this
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
0
1
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
this
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
arg (null)
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
this
this
algo
arg (null)
host
0
1
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
this
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
arg (null)
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
algo
arg (null)
this
0
1
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
this
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
arg (null)
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
0
1
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
this
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
arg (null)
this
algo
arg (null)
host
this
host
_ (null)
<anonymous>
0
1
2
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
visitor
arg (null)
this
this
algo
arg (null)
host
0
1
2
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
algo
list
Tracing the execution of a visitor
_state
_datum
_rest
“Fred”
_state
_datum
_rest
“Wilma”
_state
public Object emptyCase(…){…}public Object nonEmptyCase(…){…}
space for return valuevisitor
arg (null)
this
0
1
2
Driver:int len = list.execute(visitor, null);
LRS:public Object execute(IAlgo algo, Object arg){ return _state.execute(algo, arg, this);}
EmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.emptyCase(host, arg);}
NonEmptyState:public <I, O> O execute(IAlgo<I, E, O> algo,
LRStruct<E> host, I arg) { return algo.nonEmptyCase(host, arg);}
LengthVisitor:public Integer emptyCase(LRStruct<E> host, Object _) {
return 0; // isn't autoboxing cool :-)}
public Integer nonEmptyCase(LRStruct<E> host, Object _) {return 1 + host.getRest().execute(this, _);
}
That’s it!
Questions?
<anonymous>
• A variable used at runtime which was not explicitly declared in the program
• Used to hold the value returned by the recursive call, so that 1 can be added to it.
Variables:code vs. runtime
• In code, we declare instance variables once:public class Foo {
private Bar _b;}
• In code, we declare parameters/local variables once:public int someFunction(int x, int y) {
int z = x + y;return (z * x) / 2;
}
• These names can represent many variables at runtime.• Variable defined not just by name, but name and location
in memory.
Additional exercises
• Write a visitor for an LRS of Integers which returns the largest Integer.
• Write a visitor for an LRS of Integers, which you can assume appear in order from smallest to largest, which inserts its input in the correct (in order) position within the LRS.