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

From: Date: Thu, 09 Jun 2022 19:27:14 +0000
Subject: Re: [RFC] Short Closures 2, aka auto-capture take 3
References: 1 2 3  Groups: php.internals 
Request: Send a blank email to internals+get-117893@lists.php.net to get a copy of this message
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 () => ...ð )Â/ > > P*iæÅІK 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

« previous php.internals (#117893) next »