Category: Streams-Generators
Superclass: Stream
A Generator object provides a way to use blocks to define a Stream of many return values. The return values are computed one at a time, as needed, and hence need not even be finite. A generator block is converted to a Generator with "Generator on: [...]". The Generator itself is passed to the block, and as soon as a message like #next, #peek, #atEnd or #peekFor: is sent to the generator, execution of the block starts/resumes and goes on until the generator's #yield: method is called: then the argument of #yield: will be the Generator's next element. If the block goes on to the end without calling #yield:, the Generator will produce no more elements and #atEnd will return true. You could achieve the effect of generators manually by writing your own class and storing all the local variables of the generator as instance variables. For example, returning a list of integers could be done by setting a variable to 0, and having the #next method increment it and return it. However, for a moderately complicated generator, writing a corresponding class would be much messier (and might lead to code duplication or inefficiency if you want to support #peek, #peekFor: and/or #atEnd): in general, providing a #do:-like interface is easy, but not providing a Stream-like one (think binary trees). The idea of generators comes from other programming languages, in particular this interface looks much like Scheme streams and Python generators. But Python in turn mutuated the idea for example from Icon, where the idea of generators is central. In Icon, every expression and function call behaves like a generator, and if a statement manages scalars, it automatically uses up all the results that the corresponding generator provides; on the other hand, Icon does not represent generators as first-class objects like Python and Smalltalk do.

Method category index

instance creation (class)
stream protocol (instance)

instance creation (class)

inject: aValue into: aBlock
Return an infinite generator; the first item is aValue, the following items are obtained by passing the previous value to aBlock.

on: aBlock

Return a generator and pass it to aBlock. When #next is sent to the generator, the block will start execution, and will be suspended again as soon as #yield: is sent from the block to the generator.

on: aCollection do: aBlock

Return a generator; for each item of aCollection, evaluate aBlock passing the generator and the item.

top


stream protocol (instance)

atEnd
Answer whether more data can be generated.

next

Evaluate the generator until it generates the next value or decides that nothing else can be generated.

peek

Evaluate the generator until it generates the next value or decides that nothing else can be generated, and save the value so that #peek or #next will return it again.

peekFor: anObject

Evaluate the generator until it generates the next value or decides that nothing else can be generated, and if it is not equal to anObject, save the value so that #peek or #next will return it again.

yield: anObject

When entering from the generator the code in the block is executed and control flow goes back to the consumer. When entering from the consumer, the code after the continuation is executed, which resumes execution of the generator block.

top