> Of course, this is not an elegant solution, as it adds one more rule to the language, making it
> more complex. However, from a legacy perspective, it seems like a minimal scar.
> (to All: Please leave your opinion if you are reading this )
>
Larry’s approach seems like a horrible idea to me: it increases complexity, prevents easy
migration of existing code to an asynchronous model and is incredibly verbose for no good reason.
The arguments mentioned in https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/
are not good arguments at all, as they essentially propose explicitly reducing concurrency (by
allowing it only within async blocks) or making it harder to use by forcing users to pass around
contexts (which is even worse than function colouring https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/).
This (supposedly) reduces issues with resource contention/race conditions: sure, if you don’t use
concurrency or severely limit it, you will have less issues with race conditions, but that’s not
an argument in favour of nurseries, that’s an argument against concurrency.
Race conditions and deadlocks are possible either way when using concurrency, and the way to avoid
them is to introduce synchronisation primitives (locks, mutexes similar to the ones in https://github.com/amphp/sync/, or lockfree solutions
like actors, which I am a heavy user of), not bloating signatures by forcing users to pass around
contexts, reducing concurrency and completely disallowing global state.
Golang is the perfect example of a language that does colourless, (mostly) contextless concurrency
without the need for coloured (async/await keywords) functions and other complications.
Race conditions are deadlocks are avoided, like in any concurrent model, by using appropriate
synchronisation primitives, and by communicating with channels (actor model) instead of sharing
memory, where appropriate.
Side note, I *very* much like the current approach of implicit cancellations, because they even
remove the need to pass contexts to make use of cancellations, like in golang or amphp (though the
RFC could use some further work regarding cancellation inheritance between fibers, but that’s a
minor issue).
> Yeah, so basically, you're creating the service again and again for each coroutine if the
> coroutine needs to use it. This is a good solution in the context of multitasking, but it loses in
> terms of performance and memory, as well as complexity and code size, because it requires more
> factory classes.
>
^ this
Regarding backwards compatibility (especially with revolt), since I also briefly considered
submitting an async RFC and thought about it a bit, I can suggest exposing an event loop interface
like https://github.com/revoltphp/event-loop/blob/main/src/EventLoop.php,
which would allow userland event loop implementations to simply switch to using the native event
loop as backend (this’ll be especially simple to do for which is the main user of fibers, revolt,
since the current implementation is clearly inspired by revolt’s event loop).
Essentially, the only thing that’s needed for backwards-compatibility in most cases is an API that
can be used to register onWritable, onReadable callbacks for streams and a way to register delayed
(delay) tasks, to completely remove the need to invoke stream_select.
I’d recommend chatting with Aaron to further discuss backwards compatibility and the overall RFC:
I’ve already pinged him, he’ll chime in once he has more time to read the RFC.
~~~
To Edmond, as someone who submitted RFCs before: stand your ground, try not to listen too much to
what people propose in this list, especially if it’s regarding radical changes like Larry's;
avoid bloating the RFC with proposals that you do not really agree with.
Regards,
Daniil Gentili
—
Daniil Gentili - Senior software engineer
Portfolio: https://daniil.it <https://daniil.it/>
Telegram: https://t.me/danogentili