a list = a Linear Recursive Structure (LRS or LRStruct) What is a list? 1.the empty list is a list 2.a pair whose tail is a list is itself a list This is a recursive definition! (1) is called the base case, and (2) is called the recursive case. Note that traditional implementations do not follow this precise definition of what a list is: –many have no explicit representation of an empty list –none are recursive on the list; instead they recurse on a list node This has implications for how the structure can support extension (see Visitor support, in later slides)
States A list can therefore be in one of two states: –empty (corresponding to the base case) –non-empty (corresponding to the recursive case) The state-based implementation we will study makes this distinction explicit in the representation
Empty vs. NonEmpty state (look Ma, no NullPointerException!) An LRS object delegates all calls to its LRS State object – which can respond to all messages. Empty and NonEmpty states respond differently. There is never a null pointer in the structure! (Think about the implications of this for a while.)
What is basic (invariant) list functionality? insert new item at front remove item from front set/get first item (head) set/get rest (tail) plus (in Java) methods inherited from Object (toString, equals, etc)
How are these methods defined? public LRStruct insertFront(E item) { return _state.insertFront(this, item); } public E removeFront() { return _state.removeFront(this); } public LRStruct setDatum(E item) { return _state.setDatum(this, item); } public E getDatum() { return _state.getDatum(this); } public LRStruct setRest(LRStruct rest) { return _state.setRest(this, rest); } public LRStruct getRest() { return _state.getRest(this); }
LRStruct delegates to State! All of these methods delegate to the state of the LRStruct. States polymorphically determine what happens.
An empty LRS LRS a = new LRS(); _state LRSEmpty a
Inserting an item into an empty LRS a.insertFront(“fred”); _state LRSEmpty a
Inserting an item into an empty LRS a.insertFront(“fred”); _state LRS a Empty
Inserting an item into an empty LRS a.insertFront(“fred”); _state LRS NonEmpty a Empty _tail _dat= “fred”
Inserting an item into an empty LRS a.insertFront(“fred”); _state LRS NonEmpty a LRS Empty _state_tail _dat= “fred”
Inserting an item into an empty LRS a.insertFront(“fred”); _state LRS NonEmpty a LRS Empty _state_tail _dat= “fred”