Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a "yield return" equivalent in the D programming language?

Tags:

d

dmd

Here is a simple generator in C#.

    IEnumerable<int> Foo()     {         int a = 1, b = 1;         while(true)         {             yield return b;             int temp = a + b;             a = b;             b = temp;         }     } 

How do I write a similar generator in Digital Mars D?

(The question is about the yield return statement)

Thanks!


Update. That's interesting. Since I'm just generating a mathematical sequence, using recurrence may be a good option.

auto fib = recurrence!("a[n-1] + a[n-2]")(1, 1);  foreach (e; take(fib, 10)) // <- prints first ten numbers from the sequence {      writeln(e);  } 
like image 751
Lurkeroid Avatar asked Oct 04 '10 15:10

Lurkeroid


1 Answers

There's no exact equivalent in D. Here are some rough equivalents:

Using opApply-style internal iteration. This doesn't allow iterating over two iterators in lockstep, though:

struct Foo {     int opApply(int delegate(ref int) dg) {         int a = 1, b = 1;         int result;         while(true) {             result = dg(b);             if(result) break;             int temp = a + b;             a = b;             b = temp;         }          return result;     } }  void main() {     // Show usage:     Foo foo;     foreach(elem; foo) {         // Do stuff.     } } 

Use ranges. These are slightly harder to write in some cases, but are very efficient and allow lockstep iteration. This can also be iterated over with a foreach loop, exactly like the opApply version:

struct Foo {     int a = 1, b = 1;      int front() @property {         return b;     }      void popFront() {         int temp = a + b;         a = b;         b = temp;     }      // This range is infinite, i.e. never empty.     enum bool empty = false;      typeof(this) save() @property { return this; } } 

If you really need coroutine-style stuff you can combine ranges and opApply together using core.thread.Fiber, but you'll probably find that either ranges or opApply does what you need almost all the time.

like image 110
dsimcha Avatar answered Oct 08 '22 14:10

dsimcha