On Thu, Jun 9, 2022 at 9:29 PM Marco Pivetta <ocram...@gmail.com> wrote:
> > On Thu, 9 Jun 2022 at 21:27, Nikita Popov <nikita....@gmail.com> wrote: > >> 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 >> > > Hey Nikita, > > Do you have another example? Calling instance methods statically is... > well... deserving a hard crash :| > Maybe easier to understand if you replace Foo::bar() with parent::bar()? That's the most common spelling for this type of call. I agree that the syntax we use for this is unfortunate (because it is syntactically indistinguishable from a static method call, which it is *not*), but that's what we have right now, and we can hardly just stop supporting it. Regards, Nikita