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

Reply via email to