Hi, On jeudi 30 juin 2022 00:31:44 CEST Dan Ackroyd wrote: > On Wed, 29 Jun 2022 at 18:30, Larry Garfield <la...@garfieldtech.com> wrote: > > The conversation has died down, so we'll be opening the vote for this > > tomorrow. > I think I've just thought of a problem with the optimization bit of > 'not capturing variables if they are written to before being used > inside the closure'. > > Imagine some code that looks like this: > > // Acquire some resource e.g. an exclusive lock. > $some_resource = acquire_some_resource(); > > $fn = fn () { > // Free that resource > $some_resource = null; > } > > // do some stuff that assumes the exclusive > // lock is still active. > > // call the callback that we 'know' frees the resource > $fn(); > > That's a not unreasonable piece of code to write even if it's of a > style many people avoid. I believe in C++ it's called "Resource > acquisition is initialization", though they're trying to change the > name to "Scope-Bound Resource Management" as that is a better > description of what it is.
I feel that the RAII pattern aka SBRM / Scope-Bound Resource Management is not relevant in PHP context, and I don't believe that it's commonly used in PHP or in garbage collected language. Also, in this particular code example, using an explicit fclose() would be better in every way, including legibility and reliability, so this doesn't appear to be realistic code. Because of this, I don't think that we should be taking decisions on this feature based on this use case. I've used the RAII pattern in PHP to manage temporary files, as a best-effort way to remove them (in a destructor) when they are not used anymore. However I would not rely on this for anything more critical or anything that requires predictability in resource release timing. RAII is useful in C++ because memory is managed manually. This is not the case in PHP. It's also useful in C++ to manage other kinds of resources such as file pointers or locks. In PHP it would be dangerous because you don't realistically control the lifetime of values, so you also don't control the timing at which the resources are closed. It's too easy to extend the lifetime of a value accidentally. One way the lifetime of a value could be extended is via a reference cycle. These are easy to introduce and difficult to prevent or observe (e.g. in a test or in an assertion). An other way would be by referencing the value somewhere else. You can not guarantee that the lifetime of a value is unaffected after passing it to a function. In C++ it's different because no code would implicitly keep a reference to a variable passed to it unless it was part of that code's contract, or unless the variable was refcounted. Another factor that makes RAII un-viable in PHP is that the order of the destructor calls is unspecified. Currently, if multiple objects go out of scope at the same time, they happen to be called in a FIFO order, which is not what is needed when using the RAII pattern [0][1]. I think that RAII can only realistically be used in a non-managed, non- refcounted, non-GC language. GC or reference counting should not be used to manage anything else than memory allocation. Other languages typically have other ways to explicitly manage the lifetime of resources. Go has `defer()` [2]. Python has context managers / `with` [3], C# has `using` [4]. `with` and `using` can be implemented in userland in PHP. Because of all these reasons, I don't think that RAII in PHP is practical or actually used. So I don't think that we should be taking decisions on Short Closures based on this use case. > With the optimization in place, that code would not behave > consistently with how the rest of PHP works There exist no circumstance in PHP in which the existence of the statement `$a = null` would extend the lifetime of the value bound to `$a`. [0] Destructor order PHP: https://3v4l.org/iGAPj [1] Destructor order C++: https://godbolt.org/z/f78Pa9j69 [2] https://go.dev/doc/effective_go#defer [3] https://docs.python.org/3/reference/compound_stmts.html#with [4] https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/ keywords/using-statement Cheers, -- Arnaud Le Blanc -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php