CS 342 Lecture -*- Outline -*- * Iteration over abstract data types ** Problem how to access the elements of a collection without comprimising data abstraction? *** example: intset abstract values: finite sets of integers operations: create, insert, delete, is_in, union, size, etc. what actions could you perform on all the elements of a set: list them provide all these as part of set's interface? or: provide a tool for users to program these themselves? issues: simplicity, orthogonality, coherence *** ways to iterate over intsets 1. add indexing operation (fetch) to intset? what is the issue? 2. add operation that returns a sequence of all elements? issue: efficiency (consider searching for a negative element) 3. add operation to return the rep? what is the issue? 4. a way to get the elements one at a time abstractly, think of as yielding a sequence concretely, doesn't construct the sequence ** streams (generators) init operation, that returns a new loop_state object done? operation, that tests a loop_state to see if terminated next operation, that takes a loop_state, returns next element and modifies the loop_state (signals if done) seperate generation of sequence of items from their use allow one to hide the representation of an abstract ** CLU iterators automatic support for the above state maintained by system in iterator, init, next, and done are implicit iter like a proc yields instead of returns, use yield to produce next item ------------------ intset = cluster is elements, ... rep = array[int] % REP INVARIANT: For r: rep, r contains no duplicates % % ABSTRACTION FUNCTION: r: rep represents the set containing % just the elements of r. elements = iter(s: cvt) yields(i:int) % EFFECT: yield each element of s, once only for i: int in array[int]$indexes(s) do yield(s[i]) end end elements end intset ------------------ or one could have written: ------------------ elements = iter(s: cvt) yields(i:int) for i: int in array[int]$elements(s) do yield(i) end end elements ------------------ other examples: interval$elements traffic_light$cycle (note that this is infinite) iterators don't have to be connected with a collection --------------- blank_positions = iter() yields(int) % EFFECT: Yield 3, 7, 11 yield(3) yield(7) yield(11) end blank_positions fields = iter(s: string) yields(string) % REQUIRES: s has at least 14 characters % EFFECT: Yield each of the address fields of a pseudo-code instr. yield(string$substr(s,4,3)) yield(string$substr(s,8,3)) yield(string$substr(s,12,3)) end fields -------------- ** Implementation of CLU iterators (may be omitted) (this section needs work) body of for loop is treated as a coroutine called on each yield faster than general case for coroutines