> 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

Reply via email to