<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Iterator Blocks, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2009/07/09/iterator-blocks-part-one.aspx</link><description>There is a constant tension in language design between solving general problems and solving specific problems; finding the right spot on the general-to-specific spectrum can be quite tricky. The design of iterator blocks yields (ha ha) a germane example.</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>re: Iterator Blocks, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2009/07/09/iterator-blocks-part-one.aspx#9827587</link><pubDate>Thu, 09 Jul 2009 23:41:20 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9827587</guid><dc:creator>arnshea</dc:creator><description>&lt;p&gt;It's exactly that kind of attitude that has made for a programming language that feels light years more productive for building a very large class of applications than so many of its ancestor languages. &amp;nbsp;People don't realize that there's so much software to be built and so much hardware to throw around that the weak link in the chain is human comprehension.&lt;/p&gt;
&lt;p&gt;It strikes me that a similar analysis could be made of C# generics vs C++ templates.&lt;/p&gt;
</description></item><item><title>re: Iterator Blocks, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2009/07/09/iterator-blocks-part-one.aspx#9827656</link><pubDate>Fri, 10 Jul 2009 00:20:53 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9827656</guid><dc:creator>catbert</dc:creator><description>&lt;p&gt;Let me guess :-)&lt;/p&gt;
&lt;p&gt;Iterator blocks cannot take ref or out parameters because those cannot be warped into fields inside a helper class which implements the iterator interface.&lt;/p&gt;
&lt;p&gt;You cannot put a yield in a finally because you cannot goto into finally. Or maybe because that would break the invariant of finally clause: statements after yield might never be executed.&lt;/p&gt;
&lt;p&gt;You cannot put unsafe code in the iterator block because then you could run into a situation where one part of code that e. g. allocates non-GC-ed memory is executed, and the other part that frees it is not executed, leading to memory leaks and other scary unsafe and unmanaged stuff.&lt;/p&gt;
&lt;p&gt;(sorry for my English, I am not quite native speaker)&lt;/p&gt;
</description></item><item><title>re: Iterator Blocks, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2009/07/09/iterator-blocks-part-one.aspx#9827785</link><pubDate>Fri, 10 Jul 2009 01:47:38 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9827785</guid><dc:creator>sambo99</dc:creator><description>&lt;p&gt;A similar argument could have been made about IDisposable and using blocks, &lt;/p&gt;
&lt;p&gt;The big problem I see with this is that .Net now has 2 specific structures (foreach and using) which both could have been implemented as continuations. &lt;/p&gt;
&lt;p&gt;The restrictive nature of the implementation, kind of hurts you, you can not intercept and track exceptions in using blocks, you can not pass around foreach blocks (or track exceptions) &lt;/p&gt;
</description></item><item><title>re: Iterator Blocks, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2009/07/09/iterator-blocks-part-one.aspx#9828173</link><pubDate>Fri, 10 Jul 2009 06:59:09 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9828173</guid><dc:creator>Ajai Shankar</dc:creator><description>&lt;p&gt;Eric&lt;/p&gt;
&lt;p&gt;Guess being one of the &amp;quot;adventurous people&amp;quot; iterators &amp;amp; async have worked great for the last 5 years for me :-)&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_new" href="http://codeplex.com/easyasync"&gt;http://codeplex.com/easyasync&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Look forward to the rest of the posts in this series.&lt;/p&gt;
&lt;p&gt;Could you also elaborate on how you determine if a feature such as coroutine or continuation should be implemented in the *language or the run time*?&lt;/p&gt;
&lt;p&gt;I remember in 1.1 the undocumented hosting API hack I used to implement coroutines for .NET&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_new" href="http://msdn.microsoft.com/en-us/magazine/cc164086.aspx"&gt;http://msdn.microsoft.com/en-us/magazine/cc164086.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Also in 2.0 the hosting API was revamped to support different tasking models to address similar continuation based scenarios (and also SQL server fiber mode)&lt;/p&gt;
&lt;p&gt;Where does the language designer fit into all this?&lt;/p&gt;
&lt;p&gt;Ajai&lt;/p&gt;
</description></item><item><title>re: Iterator Blocks, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2009/07/09/iterator-blocks-part-one.aspx#9829378</link><pubDate>Sat, 11 Jul 2009 10:50:31 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9829378</guid><dc:creator>Daniel Earwicker</dc:creator><description>&lt;p&gt;What's the likelihood of being able to yield inside the try of a try/catch block in a future version? Or is there some basic reason why that can't make sense. Aside from that I think iterator methods are fine as they are - close enough to general coroutines, and lacking the &amp;quot;spooky&amp;quot; aspects of general continuations.&lt;/p&gt;
&lt;p&gt;As for yield return in a finally block, that would be odd because finally blocks run if the iterator is abandoned via Dispose. Yielding more items wouldn't be the sanest response to that.&lt;/p&gt;
</description></item><item><title>re: Iterator Blocks, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2009/07/09/iterator-blocks-part-one.aspx#9829660</link><pubDate>Sat, 11 Jul 2009 20:46:53 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9829660</guid><dc:creator>Aaron</dc:creator><description>&lt;p&gt;What's the likelihood of getting working coroutines in a future version of C# or CLR? &amp;nbsp;the problem with using iterator syntax has been demonstrated by you before:&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;IEnumerator InOrderTraverseTree() {&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (this.left != null)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;foreach(object o in this.left.InOrderTraverseTree()) &amp;nbsp;yield return o;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;yield return this.value;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (this.right != null)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;foreach(object o in this.right.InOrderTraverseTree()) yield return o;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;The problem being that you zip up and down the co-routine's call stack on every iteration step. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;Don't get me wrong, the iteration syntax captures a nice pattern. &amp;nbsp;But people have noticed that it doesn't get you as far as 'something else', though maybe they don't know the name of that 'something else' yet, having never worked in a language that has coroutines or first class continuations.&lt;/p&gt;
&lt;p&gt;I'm curious if you'd agree, but I've always thought of the thing missing from iterator syntax is the method call abstraction. &amp;nbsp;In a hypothetical co-routine environment, instead of 'yield return x', you would 'push(x)', where 'push' is some sort of callable thing -- delegate in C# parlance -- where you could pass that delegate to recursive calls.&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;// in hypothetical C#++&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;[Coroutine(IEnumerable)]&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;void InOrderTraverseTree(Action&amp;lt;object&amp;gt; push) {&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (this.left != null)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;this.left.InOrderTraverseTree(push);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;yield return this.value;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (this.right != null)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;this.right.InOrderTraverseTree(push);&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt;Slightly improved readibility, drastically improved asymptotic performance. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;One alternate approach I've heard suggested is chainable iterators -- that 'yield return' could be passed an IEnumerable to fold in. &amp;nbsp;I'm curious which you'd prefer.&lt;/p&gt;
</description></item><item><title>re: Iterator Blocks, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2009/07/09/iterator-blocks-part-one.aspx#9829972</link><pubDate>Sun, 12 Jul 2009 09:19:31 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9829972</guid><dc:creator>Gabe</dc:creator><description>&lt;p&gt;You can't yield from a finally block because yield is really a return, and you cannot return from a finally block -- you must leave the block to go to a return outside of it. And once you leave that block, there's no way to get back into the finally to resume execution on the next iteration.&lt;/p&gt;
&lt;p&gt;And if there was an unhandled exception, when would it propogate to the caller? After all the yields in the finally block had been enumerated? But what if you never finished enumerating them? And where would you put the exception in the mean time?&lt;/p&gt;
</description></item><item><title>re: Iterator Blocks, Part One</title><link>http://blogs.msdn.com/ericlippert/archive/2009/07/09/iterator-blocks-part-one.aspx#9884358</link><pubDate>Wed, 26 Aug 2009 03:24:46 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9884358</guid><dc:creator>Bob Denny</dc:creator><description>&lt;p&gt;I'm a dyed-in-the-wool YAGNI guy. Thank you for everything, including Windows Script!!! Some time I'd like you to see what I did with (every bit of) Windows Script in my astronomy automation system. You'll probably not believe it. I even found named parameters, ha ha.&lt;/p&gt;
&lt;p&gt;I love C# and have used the hell out of it for the last 5 years or so. Keep up the great work, and keep blogging. I'm reading all of the parts to this interesting article on iterators now.&lt;/p&gt;
</description></item></channel></rss>