On Thu, Jun 30, 2022 at 3:26 PM Dan Ackroyd <dan...@basereality.com> wrote: > > Hi Rowan, > > Rowan wrote: > > For that to work, it would require the variable to be captured by > > reference, not value. > > ... > > The only way for it to work would be using capture by reference (not > > supported by the proposed short syntax): > > I wrote about this before. Some of the words in the RFC are, in my > opinion, quite inaccurate: > > Danack wrote in https://news-web.php.net/php.internals/117938 : > > Those statements are true for scalar values. They are not true for objects:
But the RFC has been updated since (notably the DateTime example); do you find the current wording still inaccurate? > With automatic capturing of variables, for the code example I gave the > user would want the variable to be captured, and to them it looks like > it should be, but because of an optimization it is not. Am I missing something here? To me, it has been explained (and shown) by Rowan (and me) that the code example you gave would *not* work as expected *even without the optimization* (for it to work it would need to either capture by *reference*, or use e.g. `$some_resource->close();` [or `close($some_resource);`] instead of a destructor); but maybe we don't "expect" the same behavior in the first place? > When the code doesn't work as they expect it to, the programmer is > likely to add a var_dump to try to see what is happening. Which makes > it look like their code 'should' work, as their resource object is > still alive. This indeed seems a valid point (that adding a `var_dump($some_resource);` before the `$some_resource = null;` changes it from "not captured" to "captured", with an effect on its lifetime). But are there "real" cases where it would *actually* matter? > > In fact, the "optimisation" is in my opinion a critical part of the > > semantics, to avoid the opposite problem: > > As I said, I think that problem is a lot easier to explain "either use > long closures or change your variable name if you don't want it > captured." than trying to explain "yes, the variable is referenced > inside the closure, but it's not captured because you aren't reading > from it". Same as above. On Thu, Jun 30, 2022 at 4:19 PM Robert Landers <landers.rob...@gmail.com> wrote: > > Rowan wrote: > > No, the captured value is tied to the lifetime of the closure itself, > not the variable inside the closure. > > With the "optimization," it won't be captured at all by the closure, > possibly causing some resources to go out of scope early. And it has been explained that conversely, capturing it would possible cause some resources to "remain in scope" late. > Are > optimizations going to be applied to single-line arrow functions (I > didn't see that in the RFC, but I admittedly didn't look that hard and > I vaguely remember reading something about it in one of these > threads)? Seems so: https://github.com/php/php-src/pull/8330/files#diff-85701127596aca0e597bd7961b5d59cdde4f6bb3e2a109a22be859ab7568b4d2R7318-R7320 > If so, it will probably change some behaviors in existing > applications if they were relying on it. Perhaps static analysis tools > can detect this and inform the developer. Here too, do you have a "real" case where it would *actually* matter? > Here's Dan's code: https://3v4l.org/99XUN#v8.1.7 that he just sent, > modified to not capture the $some_resource and you can see that it is > indeed released earlier than if it were captured. And here it is "un-modified": https://3v4l.org/gZai2 where you see that calling $fn() (which internally nullifies *its local copy of* $some_resource) does *not* release; is it really what you expect? are you creating the closure only to extend the lifetime of $some_resource? Regards, -- Guilliam Xavier -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php