Coroutines in C (Simon Tatham, 2000)
chiark.greenend.org.uk
chiark.greenend.org.uk
This might have been true when the article was written, but things are slightly different today. JavaScript, Python, and C# have picked up generator primitives that can be abused to provide limited coroutine support. Lua, with actual coroutine support, is gaining in popularity. And it will be interesting to see what happens with PyPy, which has support for the Stackless Python coroutine primitive.
There are apparently lots of uncommonly used languages with coroutine support:
http://en.wikipedia.org/wiki/Coroutine#Programming_languages...
"Revisiting Coroutines" by de Moura and Ierusalimschy (http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.58.4...) is a pretty good paper about using coroutines, with Lua as the example language.
However, it's beautifully instructive, and a clever hack.
For all this and more, see his home page: http://www.chiark.greenend.org.uk/~sgtatham/ .
I think you can get a similar effect in a high-level language by transforming the logic inside your normal function into a state machine that effectively runs one line logical line of code per call. You still end up with a call stack, but you don't use it the same way.
I'm currently implementing an approximate search engine this way in a high level language. I've done some proof-of-concepts with this technique and it seems very efficient, because I can just kill the machines without having to run them to completion when I think I've found my answer (or am sure there's no answer to find).
Getting to that "a ha!" moment when I figured out that this would help (a lot) was very hard. Forcing my code to behave that way was definitely non-intuitive and challenging. Having merely gotten it working and proving my theory (it works) that it's a huge efficiency gain, I now get another crack at the next version.
I don't think it's necessary for a compiler to do the work for you, or to have it built in as a fundamental feature of a language (that certainly helps). But I do agree that without a library or (dare I say) framework, it is a bit challenging to code from scratch.
Probably the hardest part (for me), is that it breaks so many fundamental notions of programming.
One obvious feature that I'm making heavy use of is that I can get data out of the state machine on every call (that's almost the whole point for me). I can use that data and determine if I want to call it any more or just kill it (or maybe put it aside to get called later).
Perhaps more interesting, I have the opportunity to pass data into the state machine on every call down to it (not just on the initial call). That seems powerful. I already have an idea on how to utilize that.
I do agree, that at some point this technique would be more efficient if implemented in assembly than in a high-level language. My approach is probably similar to implementing a binary search in a high-level language and comparing it so a linear search in C. At this point I'll take the flexibility of the high-level language. Almost certainly a lower level implementation of the same pattern would kick butt.
[1] http://www.opengroup.org/onlinepubs/009695399/functions/make...