On 09/26/2016 02:42 AM, Jacob Carlborg wrote:
On 2016-09-25 20:16, Nick Sabalausky wrote:
I don't see why not, but there would be one notable drawback: You could
only have one instance existing at a time (per thread).

But how does it work in languages which don't pass in the state
explicitly, like with "yield" in C#?

Or async/await? I guess one doesn't call the function multiple times in
the same way instead it's done automatically under the hood, passing in
the state which might be stored in the "Task" that is returned?


I don't know about async/await, because all my C# work was with versions of C# that predated those. But as for C#'s yield functions, yes, that's my understanding: It's hidden magic automatically inserted by the compiler.

As a side note, that actually makes D's opApply a very interesting case, really:

Instead of doing like the other implementations and "yielding" by removing the top function from the callstack (ie "returning"), opApply does the oppposite: It yields by pushing whatever function it's yielding *to*, *onto* the callstack. So its state is stored on the stack, no need for magic. The downside is, that's exactly what makes it impossible for opApply to be used as a range (at least without introducing a true fiber to save/restore the callstack): popFront *must* return in order for the user's algorithm to call front and obtain the current element - because that's how the range interface works.


The above code compiles, after removing the extra "return+case:".


Really? I may have to look into this more then.

Hmm, well for starters, according to <http://dlang.org/spec/statement.html#GotoStatement>:
"It is illegal for a GotoStatement to be used to skip initializations."

Although if that's true, I don't know why that example compiled. Maybe because "foo" wasn't used from "case 2:" onward? Maybe it failed to notice the initialization since it was in an if condition? Or maybe the compiler forgot to implement the same "can't skip initialization" check for switch/case?

Reply via email to