Implementing yield (yield return) using Scala continuations

Before we introduce continuations we need to build some infrastructure. Below is a trampoline that operates on Iteration objects. An iteration is a computation that can either Yield a new value or it can be Done. sealed trait Iteration[+R] case class Yield[+R](result: R, next: () => Iteration[R]) extends Iteration[R] case object Done extends Iteration[Nothing] def … Read more

Some help understanding “yield”

A method using yield return must be declared as returning one of the following two interfaces: IEnumerable<SomethingAppropriate> IEnumerator<SomethingApropriate> (thanks Jon and Marc for pointing out IEnumerator) Example: public IEnumerable<AClass> YourMethod() { foreach (XElement header in headersXml.Root.Elements()) { yield return (ParseHeader(header)); } } yield is a lazy producer of data, only producing another item after the … Read more

When NOT to use yield (return) [duplicate]

What are the cases where use of yield will be limiting, unnecessary, get me into trouble, or otherwise should be avoided? It’s a good idea to think carefully about your use of “yield return” when dealing with recursively defined structures. For example, I often see this: public static IEnumerable<T> PreorderTraversal<T>(Tree<T> root) { if (root == … Read more

Recursion using yield

Yes, you can do this: def infinity(start): yield start for x in infinity(start + 1): yield x This will error out once the maximum recursion depth is reached, though. Starting from Python 3.3, you’ll be able to use def infinity(start): yield start yield from infinity(start + 1) If you just call your generator function recursively … Read more

Return all enumerables with yield return at once; without looping through

It is something that F# supports with yield! for a whole collection vs yield for a single item. (That can be very useful in terms of tail recursion…) Unfortunately it’s not supported in C#. However, if you have several methods each returning an IEnumerable<ErrorInfo>, you can use Enumerable.Concat to make your code simpler: private static … Read more

Performance of nested yield in a tree

You can improve performance if you unroll recurse to stack, so you will have only one iterator: public IEnumerable<Foo> GetAll() { Stack<Foo> FooStack = new Stack<Foo>(); FooStack.Push(this); while (FooStack.Count > 0) { Foo Result = FooStack.Pop(); yield return Result; foreach (Foo NextFoo in Result.MyChildren) FooStack.Push(NextFoo); } }