Hello. > > So as an outline, I would recommend: >
Yes, your suggestion is interesting. I'll think about that section next week. However, I can say that I’ve already dropped the “philosophy” section. I decided to move it into a separate article that will be available as an artifact. Such articles can be useful, but they overload the RFC. And the RFC is already large and complex, even considering that many things have been cut from it. > > The vast majority of the examples are "print Hello World" > I’ll add more realistic examples. But I won’t completely drop the echo examples where they’re the most useful. > > It's all a series > of functions that call each other to end up on a DB factory that uses a static variable, > so nothing there is injectable or testable. > Do you mean this code? ```php function getGlobalConnectionPool(): ConnectionPool { static $pool = null; if ($pool === null) { $pool = new ConnectionPool(); } return $pool; } ``` > so nothing there is injectable or testable. 1. Why must the code use DI? The use of a tool should be driven by the requirements of the task. Where do you see such requirements in the example code? There are no rules that dictate always using one pattern or another. Such rules are an anti-pattern themselves. 2. PHP has allowed testing code with factory functions using static variables for many years. > > It has the same "should be avoided in real-world development" problem, which means it doesn't tell me anything useful > If you remove the getGlobalConnectionPool function from the example, the meaning won’t change by even one percent. If a developer reading this example doesn’t understand that ConnectionPool is a dependency and how the example works in real life, then that’s clearly not a problem with the example. > > Consider: Suppose this RFC passed, but the follow-up to add a Scheduler did not pass, for > whatever reason. What does that leave us with? I think it means we have an approved RFC > that cannot be implemented. That's not-good. > Scheduler and Reactor are the implementation of this RFC. I don’t know whether they will be discussed in a separate RFC — perhaps a PR will be enough, but… To avoid ambiguity in the wording, I can mention that such components exist, without stating that they will be accepted separately. As I understand it, this resolves all concerns. > > That was not at all evident to me from reading it. > I’ll give this extra attention. > > Let me ask this: With the spawn/start/whatever keyword, what is the expected return value? > Does it block until that's done? Do I get back a future? > The spawn expression (I think this keyword will remain) returns a coroutine object. This object implements the Awaitable interface. Awaitable is not a Future, but it’s a base interface for objects that can be awaited. Since spawn returns a value that can be awaited, it can be used with await. await spawn means: wait until that coroutine finishes. await also returns a value — the result of the coroutine’s execution. > If the mental model is "take a function call like you already had The mental model that has settled in my mind over the past 3–4 weeks looks like this: 1. Create a new execution context 2. Take this callable and its parameters and run them in the new context 3. Do it when possible (though I don’t know exactly when), but not right now As far as I understand the meaning of the word spawn, it should match this model.