On Thu, Jun 9, 2022 at 8:15 PM Arnaud Le Blanc <arnaud...@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