Each time a Sequence method is called it returns the next in a series of values. They provide a natural way to represent the idiom Begin-Iterate-Terminate.
Combining these operations into a single procedure ensures the operations are invoked in proper order. If instead the operations were implemented using independent methods their global state would need to be passed between each call. In a sequence that global state is now local and is managed for you by the compiler. Each sequence does the work of three methods using less code while reducing complexity.
Within a sequence procedure, each time you want it to return a value, use a Yield statement. A Yield essentually does a return and then the next time the sequence is invoked it resumes from there. It's probably easiest to see how this works with a trivial example:
sequence Prime: A sequence of prime numbers. entry Start = 2 cell :Starting sequence value. exit N cell :Each value returned in the series. N = Start; Try starting here. IF le( N, 2 ): IF starting from 0, 1 or 2, N = 2; The first prime is 2. YIELD; First value returned is 2. . N \/= 1; Next higher odd Number. DO always: DO over the sequence, IF Is.Prime( N ): IF at a prime, YIELD; Return the current value of Count. . UNDO IF carry( N, 2 ); UNDO IF over 64 bits. N += 2; Next odd number. - return
The sequence output can then be processed with a Do-From statement.
DO P from Prime(): DO over each prime in the series, UNDO IF P > 1000; UNDO IF over 3 digits. PRINT P; List primes up to 1000. -
An example Sequence is in the partial.g file in the Phonecode program. That sequence is read by a loop in the encode.phone.g file. The load.dictionary.g method also uses a sequence from the Gilda Foundation library that reads lines of text from a file.