On Sat, Mar 8, 2025, at 09:06, Eugene Sidelnyk wrote:
>> 
> 
>> The uncoloring of functions in PHP is probably one of the most annoying 
>> aspects of fibers, IMHO. It's hard to explain unless you've been using them 
>> awhile. But, with colored functions, the caller has control over when the 
>> result is waiting on -- it could be now, it could be in a totally different 
>> part of the program, or not at all. With fibers, the author of the function 
>> you are calling has control over when the result is waited on (and they 
>> don't have control over anything they call). This can create unpredictable 
>> issues when writing code where a specific part wrote some code thinking it 
>> had exclusive access to a property/variable. However, someone else changed 
>> one of the functions being called into an async function, making that 
>> assumption no longer true.
>> 
>> With colored functions, the person making changes also has to update all the 
>> places where it is called and can validate any assumptions are still going 
>> to be true; uncolored functions means they almost never do this. This 
>> results in more work for people implementing async, but more correct 
>> programs overall.
>> 
>> But back to the awaiting on results. Say I want to read 10 files:
>> 
>> for ($i = 0; $i < 10; $i++) $results[] = file_get_contents($file[$i]);
>> 
>> Right now, we have to read each file, one at a time, because this is 
>> synchronous. Even with this RFC and being in a fiber, the overall execution 
>> might be non-blocking, but the code still reads one file after another 
>> sequentially. Fibers do not change this.
>> 
>> With this RFC (in its original form), we will be able to change it so that 
>> we can run it asynchronously though and choose when to wait:
>> 
>> for($i = 0; $i < 10; $i++) $results[] = async\async(fn($f) => 
>> file_get_contents($f), $file[$i]);
>> // convert $results into futures somehow -- though actually doesn't look 
>> like it is possible.
>> $results = async\awaitAll($results);
>> 
>> In that example, we are deliberately starting to read all 10 files at the 
>> same time. If we had colored functions (aka, async/await) then changing 
>> file_get_contents to async would mean you have to change everywhere it is 
>> called too. That means I would see that file_get_contents is synchronous and 
>> be able to optimize it without having to even understand the reasoning (in 
>> most cases). I was a user of C# when this happened to C#, and it was a 
>> pain... So, at least with PHP fibers, this won't be AS painful, but you 
>> still have to do some work to take full advantage of them.
>> 
>> I kind of like the idea of a nursery for async, as we could then update 
>> file_get_content's return type to something like 
>> string|false|future<string|false>. In non-async, you have everything behave 
>> as normal, but inside a nursery, it returns a future that can be awaited 
>> however you want and is fully non-blocking. In other words, simply returning 
>> a future is enough for the engine to realize it should spawn a fiber 
>> (similar to how using yield works with generators). 
>> 
>> In any case, I believe that a nursery requires the use of colored functions. 
>> That may be good or bad, but IMHO makes it much more useful and easier to 
>> write correct and fast code.
>> 
> 
> 
> In my opinion, colored functions is the worst thing that could happen to PHP.
> 
> https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function
> Describes quite expressively what's wrong about this approach.
> 
> As the result, you will make everything async.
> Want a repository? It will be all async.
> Want a logger? Also async.
> Need to cache something? Make it async.
> 
> This is going to be a ton of changes, when currently sync (blue function) 
> will have to become async (red one).
> 
> The way amphp goes - it's the right way. They have had this problem of 
> red-blue functions a long ago until Fibers came into place.
> 
> What they used until third version is generator-based coroutines, so that 
> instead of returning actual object, you spoil the signature of the function 
> and return generator that will return that object (iow, "Promise").
> 
> This is just annoying, and IMO should not be considered.

My point in the email is that this happens anyway. With colored functions, you 
/*always/* decide how to handle async. Which, as you mentioned, can be 
annoying. With uncolored functions, you */never/* get to decide unless you wrap 
it in a specific form (async\run or async\async, in this RFC), which ironically 
colors the function. I can't think of any way around it. My biggest issue with 
this RFC is that it results in **multiple** colors: FiberHandle, Future, and 
Resume. 

— Rob

Reply via email to