> Edmond Dantes <edmond.ht@gmail.com> 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