On 09/24/2016 09:14 PM, Chris Wright wrote:
On Sat, 24 Sep 2016 11:49:24 -0400, Nick Sabalausky wrote:
My understanding is that C#'s coroutines, under the hood, work the same
way as C's Protothreads library:

You mean async/await, which is a compiler-provided CPS transformation on
top of the Task API.


No, I mean "yield". My C# work was all before async/await.

First, only C#'s coroutines can yield, not regular functions called by a
coroutine.

Because it's the continuation passing style, not a full thread of
execution. That makes it moderately painful to use under normal
circumstances and entirely unsuitable in other cases.


If I understand correctly what you mean by "continuation passing style", then yes, it sort of is, but only behind-the-scenes. The only recognizable effect of that is that yield can only break out of one level of the call stack at a time (just like how return only ever returns from the current function, no further - unless you use Ruby, but well, let's not go there...).

The "turning functions inside-out" effect of continuation passing is exactly what input ranges suffer from[1] - and is exactly what stackless coroutines *avoid*.


Look at Node.js and Vert.x. It's not a barrier to the market to force
programmers to manually execute the CPS transformation.

Speaking as a long-time web developer, most (not all) web developers are fully-acclimated to eating shit sandwiches and convincing themselves they like it. Hence their tolerance for what Node.js does to their code (among other issues with it, like...using JS...on the server...).

Obviously I'm being colorfully figurative there, but I'm sure you knew that ;)


Fibers are more convenient. They also have a large, upfront cost, but
they have the advantage of treating the stack like a stack. It breaks
fewer assumptions about performance.


You may want to give C's protobuf or C#'s yield-based generator functions a try. Yes, true, they're not as convenient as actual fibers, but there's a LOT they let you do painlessly (far more painlessly than writing input ranges[1]) without the fiber overhead - think opApply but without the complete and total incompatibility with functions that operate on ranges.

[1] Note I mean actually writing an input range itself. *Using* an input range is wonderfully pleasant. But writing them turns all my logic inside out, somewhat like Node.js-style callback hell (or ActionScript2 back in my day).

Reply via email to