Re: [RFC] Short Closures 2, aka auto-capture take 3

From: Date: Thu, 09 Jun 2022 19:28:59 +0000
Subject: Re: [RFC] Short Closures 2, aka auto-capture take 3
References: 1 2 3 4  Groups: php.internals 
Request: Send a blank email to internals+get-117894@lists.php.net to get a copy of this message
On Thu, 9 Jun 2022 at 21:27, Nikita Popov <nikita.ppv@gmail.com> wrote: > On Thu, Jun 9, 2022 at 8:15 PM Arnaud Le Blanc <arnaud.lb@gmail.com> > wrote: > >> Hi, >> >> On jeudi 9 juin 2022 18:46:53 CEST Marco Pivetta wrote: >> > ## nesting these functions within each other >> > >> > What happens when/if we nest these functions? Take this minimal example: >> > >> > ```php >> > $a = 'hello world'; >> > >> > (fn () { >> > (fn () { >> > echo $a; >> > })(); >> > })(); >> > ``` >> >> Capture bubbles up. When an inner function uses a variable, the outer >> function >> in fact uses it too, so it's captured by both functions, by-value. >> >> This example prints "hello world": The inner function captures $a from >> the >> outer function, which captures $a from its declaring scope. >> >> This is equivalent to >> >> ```php >> (function () use ($a) { >> (function () use ($a) { >> echo $a; >> })(); >> })(); >> ``` >> >> > ## capturing $this >> > >> > In the past (also present), I had to type static fn () => >> > ... or >> `static >> > function () { ...` all over the place, to avoid implicitly binding >> $this >> > to a closure, causing hidden memory leaks. >> > >> > Assuming following: >> > >> > * these new closures could capture $this >> > automatically, once detected >> > * these new closures can optimize away unnecessary variables that >> aren't >> > captured >> > >> > Would that allow us to get rid of static fn () { >> > declarations, when >> > creating one of these closures in an instance method context? >> >> It would be great to get rid of this, but ideally this would apply to >> Arrow >> Functions and Anonymous Functions as well. This could be a separate RFC. >> > > I've tried this in the past, and this is not possible due to implicit > $this uses. See > > https://wiki.php.net/rfc/arrow_functions_v2#this_binding_and_static_arrow_functions > for a brief note on this. The tl;dr is that if your closure does "fn() => > Foo::bar()" and Foo happens to be a parent of your current scope and bar() > a non-static method, then this performs a scoped instance call that > inherits $this. Not binding $this here would result in an Error exception, > but the compiler doesn't have any way to know that $this needs to be bound. > > Regards, > Nikita > Hey Nikita, Do you have another example? Calling instance methods statically is... well... deserving a hard crash :| Marco Pivetta https://twitter.com/Ocramius https://ocramius.github.io/

« previous php.internals (#117894) next »