> Edmond Dantes <[email protected]> hat am 22.11.2025 13:37 CET geschrieben:
> 
>  
> > basically in $result = foo(spawn(bar(baz(file_get_contents())))); 
> > file_get_contents() receives outside context from spawn() to turn into 
> > async mode.
> > Also foo(), bar(), baz() can be in different namespaces, different classes, 
> > so by looking at the code calling file_get_contents(), it's not clear if 
> > the result is sync or async.
> 
> Ok, then let’s look in detail at what is happening.
> 
> > foo(spawn(bar(baz(file_get_contents()))))
> 
> i.e.
> 
> ```php
> $result = foo(spawn(bar(...), fn () => baz(file_get_contents())));
> ```
> 
> Did I understand the code correctly?
> (Assume there was also some parameter there, like a file name.)
> 
> 1. We call `bar` in a separate coroutine, which
> 2. First calls `file_get_contents`
> 3. Then passes the result to the function `baz()`
> 
> Is that correct?
> 
> > Also foo(), bar(), baz() can be in different namespaces, different classes, 
> > so by looking at the code calling file_get_contents(), it's not clear if 
> > the result is sync or async.
> If we are discussing the code above, then it returns a Promise not of
> the file-reading result.
> This is a completely different logic, and here the programmer clearly
> intended to do something else.
> What if the function baz replaces every a character with baz? It's ok.
> 
> ```php
> $foo = file_get_contents('foo.txt'); // sync
> $result = spawn($foo); // error because $foo is string
> ```
> 
> Here I don’t understand why someone would intentionally write incorrect code.
> 
> Code:
> ```php
> $result = foo(file_get_contents('foo.txt'));
> 
> // equivalent to
> // the code below has no practical purpose
> 
> $result = foo(await(spawn(file_get_contents(...), 'foo.txt')));
> ```
> 
> Is that correct?

So I guess you want to use spawn() in a similar way as call_user_func() works.
This changes the behavior of file_get_contents() from the outside, so it gives 
file_get_contents() async context from the outside to behave differently.
Assuming every io operation inside spawn() runs async, I guess it's not 
possible to mix sync and async io inside of one function.

As mentioned before I'm not suggesting to use coroutines for async io. My 
recommendation would be implementing new functions for async io and a promise 
object. Having everything that's executed async explicitly named "_async" helps 
a lot when reading and understanding userland code.

Regarding Coroutines in Go from userland perspective: the idea is nice but 
often fails with deadlocks, hanging processes and having to run a "Data Race 
Detector" all the time. Sure it's always the developers fault, but it happens 
too often.

Best Regards
Thomas

Reply via email to