I'd say this argument on which is "better", yield or ranges, is a problem ill posed.

Yeah, since yielding is just a convenient way to implement an input range, asking which is better is like asking "Which is better, pick-up trucks or vehicles?"

"yield" adds real, nontrivial value, and is not entirely implementable as a library. Walter and I saw some uses of it in C# at Lang.NEXT that were quite impressive.

On the other hand yield's charter is limited when compared to that of ranges. Yield goes with the very simple "go through everything once" functionality, which is essentially input ranges - only a tiny part of ranges can do.

"yield" adds real, nontrivial value, and is not entirely implementable as a library. Walter and I saw some uses of it in C# at Lang.NEXT that were quite impressive.

Agreed. However, I have been looking at D's Fibers and I wonder if an optimized implementation of them could provide the same functionality reasonably well:

https://www.semitwist.com/articles/article/view/combine-coroutines-and-input-ranges-for-dead-simple-d-iteration

The only problem is performance (and perhaps memory usage, but there are ways to reduce that). Someone reported that a trivial fiber-based forward range had 26x the overhead of opApply for iteration (70s vs 2.7s for 1 billion iterations). I wonder if the fiber-switching could be optimized? But I looked at core/thread.d and unless I'm missing something, the fiber switch does not appear to do much work: it calls Thread.getThis() twice per switch (= 4 times per iteration), getStackTop() (= rt_stackTop) once, and a naked asm routine with 21 asm instructions. The entire yield() process contains no branches; call() additionally calls setThis() twice and checks if the Fiber threw an exception. What's the easiest way to time something in D? I'm curious if Thread.getThis() (= TlsGetValue()) is the bottleneck.

Anyway, stack-switching lets you do not only the same things as C# 2's "yield return" but as far as I can tell, it can also do everything that C# 5's "async/await" can do and more:

http://qscribble.blogspot.ca/2012/07/asyncawait-vs-stack-switching.html

i.e. stack switching can accomplish tasks that async/await cannot, while I don't know of any cases of the reverse. async is more limited because all functions involved in an async task must be explicitly marked and transformed by the compiler, but stack switching works no matter what code is involved; even C code can be called on an asynchronous fiber task.

Reply via email to