In the last few days I've been playing with continuations and generators. I think I now understand how they work pretty well, and I could make the generator example pretty fast using continuations (much to my surprise, 5 times faster than with processes).

Like in Python, generators are a quick way to make a Stream object out of a block, like this:

    ^Generator on: [ :gen |
        | i |
        i := 1.
        [ gen yield: i. i := i + 1 ] repeat ]

This would return an infinite stream giving the natural numbers. You can use any finite prefix of it with something like "gen next: 10" (returning the first 10 numbers). More interesting example:

    Generator on: [ :gen |
        | a b c |
        a := b := 1.
        [ gen yield: a. c := a + b. a := b. b := c ] repeat ].

You can also have finite generators, as simple as

    Generator on: [ :gen | gen yield: 1 ].

or even

    Generator on: [ :gen | ].


Other example include creating stream decorators, like the ones that 2.3.5 moved into the main image.

    Stream >> lines [
        ^Generator on: [ :gen |
            [ self atEnd ] whileFalse: [ gen yield: nextLine ] ] ]

    Stream >> select: aBlock [
        ^Generator on: [ :gen || obj |
            [ self atEnd ] whileFalse: [
                obj := self next.
                (aBlock value: obj) ifTrue: [ gen yield: obj ] ] ] ]

(Of course the performance would be worse than with custom streams, but for scripting usage there could be an advantage).

I would like to know if there is interest in moving generators (and, as a prerequisite, continuations) to the main image.

Paolo


_______________________________________________
help-smalltalk mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/help-smalltalk

Reply via email to