| |
| Posted by Richard (Rikki) Andrew Cattermole in reply to Sebastiaan Koppe | PermalinkReply |
|
Richard (Rikki) Andrew Cattermole
Posted in reply to Sebastiaan Koppe
| On 06/08/2024 3:50 AM, Sebastiaan Koppe wrote:
> On Monday, 5 August 2024 at 01:36:31 UTC, Richard (Rikki) Andrew Cattermole wrote:
>> Coroutines is a stack machine transformed representation for a function. It enables storing the state of a function externally to the stack to allow for high throughput event handling.
>
> Thank you for spearheading this. Having coroutines in the language would be a big step forward, and hopefully pave the way for more non-blocking programming in D.
>
> There are a few points I would like to bring up early though.
>
> - I see no mention of C++'s coroutines. I think it would be good to learn from their design and implementation.
>
> - As you might know I am a big proponent of C++'s Senders/Receivers (a.k.a. P2300). One awesome integration they have is that Senders can be awaited by coroutines, and coroutines can await Senders. This allows for users to pick their preference, e.g. use convenient coroutines but suffer some allocation costs, and use Senders for more performant sections if need be. See
> https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2300r7.html#design-awaitables-are-senders and https://ericniebler.com/2024/02/04/what-are-senders-good-for-anyway/
My conclusion about P2300 is that it is all library code. This DIP would allow you to implement it. Although some language integration may be missing as the data processing use case is not covered here (I have no experience with it in context and so currently I am not the best person for it).
> - I don't understand the choice for `@async`. Sometimes resembling the word "coroutine" would be better in my opinion.
It was ``@co`` for a long time.
I had a number of people request ``async`` instead.
> - In `while(Future!string readLine = socket.readUntil("\n"))` I suspect it to do an explicit await. How does that work?
When a coroutine is acquired, it'll yield automatically, it is implicit.
We may want to support explicit yielding via a multiple return.
I should probably add this, however I'm divided upon it currently. Need time to think about it some more.
> - I find the use of `Future` a bit confusing. Futures generally carry too much synchronisation overhead with them and I doubt coroutines need a full Future implementation anyway. Perhaps call it a Task like they do in C++?
This DIP does not propose library code. You are free to write whatever library code you want and have it construct itself from the language representation of a coroutine.
This is a key design goal as there is a good chance we'll want different solutions for different tasks. Being stuck with only one solution (like how new'ing a class calls a specific hook) will only lead to people being unhappy.
Note: we can introduce hooking into a specific library with a new expression, however that is not present in this DIP as we have enough to get on with with just this DIP.
> - The use of `@isasync` is a bit too cute for me. It also hides the fact sometime is a coroutine.
I want to be placing a lot more emphasis on UDA's like ``@Route``, what we do right now with reflection is far too costly in terms of how to register symbols.
But yes, I do want to hide that it is a coroutine. The average person shouldn't have to care if its asynchronous of synchronous, it does not enable them to archive business goals faster.
> - Instead of allowing a coroutine in a function that is not a coroutine itself - and injecting a blocking call - I would require explicit call to evaluate the coroutine instead. No magic.
And that is library code ;)
But yes, I did try to explain that you did not need language integration for this. In fact the prime sieve example show cases exactly what you suggest!
> - Can coroutines be continued on another thread, assuming sequential consistency?
Yes. There is nothing preventing it. There is also nothing making it safe either.
|