350 likes | 490 Views
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.
E N D
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.
SumVisitorsolution public 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, IAlgoalgo, Object argut){ return algo.emptyCase(host, input); } • NonEmpty state: public Object execute(LRS host, IAlgoalgo, 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 visitor Tracing the execution of a visitor public Object emptyCase(…){…} public Object nonEmptyCase(…){…} _state Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } “Fred” _datum _rest _state “Wilma” _datum _rest _state
list visitor Tracing the execution of a visitor space for return value algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} _state Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } “Fred” _datum _rest _state “Wilma” _datum _rest _state
list Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } Polymorphic method call visitor Tracing the execution of a visitor space for return value algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} _state “Fred” _datum _rest _state “Wilma” _datum _rest _state
list visitor Tracing the execution of a visitor algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} algo arg (null) host _state this Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } “Fred” _datum _rest _state “Wilma” _datum _rest _state
list visitor Tracing the execution of a visitor algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} algo arg (null) host _state this Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } host “Fred” _ (null) <anonymous> _datum _rest this _state “Wilma” _datum _rest _state
list visitor Tracing the execution of a visitor algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} algo arg (null) host _state this Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } host “Fred” _ (null) <anonymous> _datum _rest this algo arg (null) this _state “Wilma” _datum _rest _state
list Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } Polymorphic method call visitor Tracing the execution of a visitor algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} algo arg (null) host _state this host “Fred” _ (null) <anonymous> _datum _rest this algo arg (null) this _state “Wilma” _datum _rest _state
list visitor Tracing the execution of a visitor algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} algo arg (null) host _state this Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } host “Fred” _ (null) <anonymous> _datum _rest this algo arg (null) this _state algo arg (null) host “Wilma” this _datum _rest _state
list visitor Tracing the execution of a visitor algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} algo arg (null) host _state this Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } host “Fred” _ (null) <anonymous> _datum _rest this algo arg (null) this _state algo arg (null) host “Wilma” this _datum _rest host _ (null) <anonymous> this _state
list visitor Tracing the execution of a visitor algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} algo arg (null) host _state this Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } host “Fred” _ (null) <anonymous> _datum _rest this algo arg (null) this _state algo arg (null) host “Wilma” this _datum _rest host _ (null) <anonymous> this algo _state arg (null) this
list visitor Tracing the execution of a visitor algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} algo arg (null) host _state this Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } host “Fred” _ (null) Polymorphic method call <anonymous> _datum _rest this algo arg (null) this _state algo arg (null) host “Wilma” this _datum _rest host _ (null) <anonymous> this algo _state arg (null) this
list visitor Tracing the execution of a visitor algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} algo arg (null) host _state this Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } host “Fred” _ (null) <anonymous> _datum _rest this algo arg (null) this _state algo arg (null) host “Wilma” this _datum _rest host _ (null) <anonymous> this algo _state arg (null) this algo arg (null) host this
list visitor Tracing the execution of a visitor algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} algo arg (null) host _state this Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } host “Fred” _ (null) <anonymous> _datum _rest this algo arg (null) this _state algo arg (null) host “Wilma” this _datum _rest host _ (null) <anonymous> this algo _state arg (null) this algo arg (null) host this host 0 _ (null) this
list visitor Tracing the execution of a visitor algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} algo arg (null) host _state this Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } host “Fred” _ (null) <anonymous> _datum _rest this algo arg (null) this _state algo arg (null) host “Wilma” this _datum _rest host _ (null) <anonymous> this algo _state arg (null) this algo arg (null) host this 0
list visitor Tracing the execution of a visitor algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} algo arg (null) host _state this Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } host “Fred” _ (null) <anonymous> _datum _rest this algo arg (null) this _state algo arg (null) host “Wilma” this _datum _rest host _ (null) <anonymous> this algo _state arg (null) this 0
list visitor Tracing the execution of a visitor algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} algo arg (null) host _state this Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } host “Fred” _ (null) <anonymous> _datum _rest this algo arg (null) this _state algo arg (null) host “Wilma” this _datum _rest host _ (null) <anonymous> this _state 0
list visitor Tracing the execution of a visitor algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} algo arg (null) host _state this Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } host “Fred” _ (null) <anonymous> _datum _rest this algo arg (null) this _state algo arg (null) host “Wilma” this _datum _rest host _ (null) <anonymous> this _state 1 0
list visitor Tracing the execution of a visitor algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} algo arg (null) host _state this Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } host “Fred” _ (null) <anonymous> _datum _rest this algo arg (null) this _state algo arg (null) host “Wilma” this _datum _rest _state 1 0
list visitor Tracing the execution of a visitor algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} algo arg (null) host _state this Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } host “Fred” _ (null) <anonymous> _datum _rest this algo arg (null) this _state “Wilma” _datum _rest _state 1 0
list visitor Tracing the execution of a visitor algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} algo arg (null) host _state this Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } host “Fred” _ (null) <anonymous> _datum _rest this _state “Wilma” _datum _rest _state 1 0
list visitor Tracing the execution of a visitor algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} algo arg (null) host _state this Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } host “Fred” _ (null) <anonymous> _datum _rest this _state “Wilma” _datum _rest 2 _state 1 0
list visitor Tracing the execution of a visitor algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} algo arg (null) host _state this Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } “Fred” _datum _rest _state “Wilma” _datum _rest 2 _state 1 0
list visitor Tracing the execution of a visitor space for return value algo arg (null) this public Object emptyCase(…){…} public Object nonEmptyCase(…){…} _state Driver: intlen = list.execute(visitor, null); LRS: public Object execute(IAlgoalgo, 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, _); } “Fred” _datum _rest _state “Wilma” _datum _rest 2 _state 1 0
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 intsomeFunction(intx, inty) { intz = 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.