Download presentation
Presentation is loading. Please wait.
1
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
2
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 Object emptyCase(LRS host, Object _){ return 0; } public Object nonEmptyCase(LRS host, Object _){ return 1 + host.getRest().execute(this,_); }
3
‘execute’ definition in states Empty state: public Object execute(LRS host, IAlgo visitor, Object input){ return visitor.emptyCase(host, input); } NonEmpty state: public Object execute(LRS host, IAlgo visitor, Object input){ return visitor.nonEmptyCase(host, input); }
4
Now let’s trace execution of the visitor LRStruct list = new LRStruct (); list.insertFront(“Wilma”).insertFront(“Fred”); LengthVisitor visitor = new LengthVisitor (); int len = list.execute(visitor,null); System.out.println(“Length is ” + length); Focus on the evaluation of: list.execute(visitor,null)
5
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 inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
6
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 value visitor inp (null) this Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
7
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 value visitor inp (null) this Polymorphi c method call Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
8
algo list Tracing the execution of a visitor _state _datum _rest “Fred” _state _datum _rest “Wilma” _state public Object emptyCase(…){…} public Object nonEmptyCase(…){…} visitor inp (null) this algo input (null) owner Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
9
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 inp (null) this algo input (null) owner this host _ (null) Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
10
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 inp (null) this algo input (null) owner this host _ (null) algo inp (null) this Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
11
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 inp (null) this algo input (null) owner this host _ (null) algo inp (null) this Polymorphi c method call Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
12
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 inp (null) this algo input (null) owner this host _ (null) algo inp (null) this algo input (null) owner Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
13
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 inp (null) this algo input (null) owner this host _ (null) algo inp (null) this algo input (null) owner this host _ (null) Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
14
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 inp (null) this algo input (null) owner this host _ (null) algo inp (null) this algo input (null) owner this host _ (null) algo inp (null) this Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
15
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 inp (null) this algo input (null) owner this host _ (null) algo inp (null) this algo input (null) owner this host _ (null) algo inp (null) this Polymorphi c method call Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
16
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 inp (null) this algo input (null) owner this host _ (null) algo inp (null) this algo input (null) owner this host _ (null) algo inp (null) this algo input (null) owner Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
17
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 inp (null) this algo input (null) owner this host _ (null) algo inp (null) this algo input (null) owner this host _ (null) algo inp (null) this algo input (null) owner 0 host _ (null) this Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
18
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 inp (null) this algo input (null) owner this host _ (null) algo inp (null) this algo input (null) owner this host _ (null) algo inp (null) this algo input (null) owner 0 Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
19
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 inp (null) this algo input (null) owner this host _ (null) algo inp (null) this algo input (null) owner this host _ (null) algo inp (null) this 0 Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
20
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 inp (null) this algo input (null) owner this host _ (null) algo inp (null) this algo input (null) owner this host _ (null) 0 Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
21
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 inp (null) this algo input (null) owner this host _ (null) algo inp (null) this algo input (null) owner this host _ (null) 0 1 Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
22
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 inp (null) this algo input (null) owner this host _ (null) algo inp (null) this algo input (null) owner 0 1 Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
23
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 inp (null) this algo input (null) owner this host _ (null) algo inp (null) this 0 1 Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
24
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 inp (null) this algo input (null) owner this host _ (null) 0 1 Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
25
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 inp (null) this algo input (null) owner this host _ (null) 0 1 2 Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
26
algo list Tracing the execution of a visitor _state _datum _rest “Fred” _state _datum _rest “Wilma” _state public Object emptyCase(…){…} public Object nonEmptyCase(…){…} visitor inp (null) this algo input (null) owner 0 1 2 Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
27
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 value visitor inp (null) this 0 1 2 Driver: int len = list.execute(visitor, null); LRS: public Object execute(IAlgo algo, Object inp){ return _state.execute(algo, inp, this); } EmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.emptyCase(host, arg); } NonEmptyState: public O execute(IAlgo algo, LRStruct host, I arg) { return algo.nonEmptyCase(host, arg); } LengthVisitor: public Integer emptyCase(LRStruct host, Object _) { return 0; // isn't autoboxing cool :-) } public Integer nonEmptyCase(LRStruct host, Object _) { return 1 + host.getRest().execute(this, _); }
28
That’s it! Questions?
29
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.
30
A solution public class SumVisitor implements IAlgo { // The answer in the case of an empty list is zero // (because zero is the identity element of addition). public Integer emptyCase(LRStruct 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 host, Object _) { return host.getDatum() + host.getRest().execute(this, _); }
31
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.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.