<div class="gmail_quote">On Mon, Dec 14, 2009 at 4:28 PM, Igor Stasenko <span dir="ltr">&lt;<a href="mailto:siguctua@gmail.com">siguctua@gmail.com</a>&gt;</span> wrote:<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

As to me, that CoroutineReadStream is nice wrapping , providing a<br>
transformation from block iterators<br>
to stream. It switching from the &#39;push&#39; logic (where provider pushing<br>
values to consumer) to &#39;pull&#39; (where consumer asks provider to give<br>
next value(s), when ready to process next value).<br>
<br>
An iteration blocks usually don&#39;t decide if they willing to get next<br>
value or when (hence &#39;push&#39;), and as a consequence its hard to switch<br>
the iterator&#39;s logic in the middle of iteration.</blockquote><div><br></div><div>Yes, precisely.  I find it particularly handy when dealing with parsers.  Parsers (i.e. combinatorial parsers) usually use the activation stack to keep track of their progress and do their work.  This means they need to drive execution.  For those that are familiar with PEGs and grammars that don&#39;t make use of a lexer or tokenizer, you may know that dealing with whitespace adds a lot of clutter to a grammar.  Since we can have PEGs that are designed to work with arbitrary objects and not just characters, you could solve this problem by first creating a token parser that transforms characters into tokens, omitting whitespace.  Next, you have the parser for your language that transforms the tokens into whatever you like.  Due to the usage of the activation stack by the token parser I mentioned, it&#39;s not easy to chain the parsers together.  CoroutineReadStream makes it simpler to do. </div>
<div><br></div><div>Here&#39;s an overly simplified and contrived illustration:</div><div><br></div><div><div>streamOfTokens := </div><div><span class="Apple-tab-span" style="white-space:pre">        </span>CoroutineReadStream onBlock: </div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>[ :outputStream |</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>tokenParser </div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>parse: someCharacterStream </div>
<div><span class="Apple-tab-span" style="white-space:pre">                        </span>into: </div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>[ :token |</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>outputStream acceptNextObject: token]].</div>
<div><br></div><div>someLanguageParser</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>parse: streamOfTokens</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>into:</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>[ :parseNodeOrSomething |</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>self doSomethingWith: parseNodeOrSomething].</div><div><br></div></div><div><br></div><div>- Stephen</div></div>