I have been using yield in many of my Python programs, and it really clears up the code in many cases. I blogged about it and it is one of my site's popular pages.
C# also offers yield – it is implemented via state-keeping in the caller side, via an automatically generated class keeps the state, local variables of the function, etc.
Now, I am reading about C++0x and its additions, and while reading about the implementation of lambdas in C++0x, I find out it was done via automatically generated classes too, equipped with operator() storing the lambda code! The natural question formed: they did it for lambdas, why not consider it for supporting yield, too?
Surely they can see the value of co-routines... so I can only guess that they consider macro-based implementations (such as Simon Tatham's) to be an adequate substitute. They are not, however, for many reasons: callee-kept state, non-reentrant, macro-based (that alone is reason enough), etc.
Edit: yield
doesn't depend on garbage collection, threads, or fibers. You can read Simon's article to see that I am talking about the compiler doing a simple transformation, such as:
int fibonacci() {
int a = 0, b = 1;
while (true) {
yield a;
int c = a + b;
a = b;
b = c;
}
}
Into:
struct GeneratedFibonacci {
int state;
int a, b;
GeneratedFibonacci() : state (0), a (0), b (1) {}
int operator()() {
switch (state) {
case 0:
state = 1;
while (true) {
return a;
case 1:
int c = a + b;
a = b;
b = c;
}
}
}
}
Garbage collection? No. Threads? No. Fibers? No. Simple transformation? Arguably, yes.