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

Reply via email to