A Pipe to the Future

Jason Johnson jason.johnson.081 at gmail.com
Thu Sep 6 04:52:59 UTC 2007


On 9/6/07, Peter William Lount <peter at smalltalk.org> wrote:
> Hi,
>
> I am wondering if the following would be possible and if so how?
>
> aProcess := [ "a block that pumps out continuous values"] fork.
> bProcess := [:in | in someOperation ] fork.
>
> "pipe the results of process a into process b like in unix shell"
> aProcess asPipeInto: bProcess.
>
> or
>
> aProcess | bProcess
>
> Would a shared queue be needed? Or some other concurrency control
> mechanism for sharing the output results.
>
> Unfortunately blocks don't pump out multiple values... or fortunately
> they don't.
>
> Just a thought.
>
> Cheers,
>
> Peter

It depends on what you are asking.  If you are trying to make a
"worker thread" type pattern in Smalltalk, then Michael's message will
be what you want.  If you are talking about the functional programming
aspect [1] then you might want to look at my LazyList package on
Squeak source.

It allows easily creating generators as:

LazyList enummerateFrom: 0 with: [:e| e + 2]    "infinite list of even
numbers, starting at 0"

and defines many functional maps, transforms and reductions with a
Smalltalk naming convention, e.g.:

"LazyList equivalent of the example unix expression"

(((LazyList fromList: (file contents))
  select: [:e| e = value])
    reject: [:e| e = otherValue)
      inject: 0 into: [:l :r| l + 1 ]   "NOTE: list values ignored,
we're only counting them"

"Don't actually need LazyList here.  But you could use it in the case
that the file has no end (e.g. /dev/random), but then you would have
to remove the reduce operation"

"Sieve Of Eratosthenes"

SomeClass>>sieve: aLazyList
  ^ LazyList
      cons: aLazyList first
      with: (LazyList delay:
         [ SomeClass sieve: aLazyList allButFirst
             select [:e|  (e \\ aLazyList first = 0) not ] ])

allPrimes := SomeClass sieve: (LazyList enummerateFrom: 2 with: [:e| e + 1])
"NOTE: This returns immediately.  But just don't call: allPrimes at:
10000000 on an x486"

Hrm, I see some refactoring opportunities here.  with: should always
take a block and delay it.  I would have used that here for clarity
but I'm sure if I did someone would try this and then ask why it
doesn't work. :)  I also should change "cons" to "with" (i.e.
#with:with:) to be consistent with Smalltalk usage.

[1] The statement:

cat file | grep value | grep -v otherValue | wc -l

is basically functional programming.  That statement has a generator,
two filters and a reduction.



More information about the Squeak-dev mailing list