# RFC [Discussion]: Closure self-reference

- Thread: https://externals.io/message/120518
- Original archive: https://news-web.php.net/php.internals/120518
- Started by Dan Ackroyd on 2023-06-03T19:11:21+00:00
- Messages: 8
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #120518 — Dan Ackroyd — 2023-06-03T19:11:21+00:00

URL: https://externals.io/message/120518#120518

Hi internals,

I'm now opening the discussion for the Closure self-reference RFC:
https://wiki.php.net/rfc/closure_self_reference

This was previously discussed as a draft here:
https://externals.io/message/112216#112216

Thank-you to KapitanOczywisty for the implementation.

cheers
Dan
Ack

---

## #120519 — Juliette Reinders Folmer — 2023-06-04T11:06:06+00:00

URL: https://externals.io/message/120518#120519 · In reply to: #120518

> Hi internals,
>
> I'm now opening the discussion for the Closure self-reference RFC:
> https://wiki.php.net/rfc/closure_self_reference
>
> This was previously discussed as a draft here:
> https://externals.io/message/112216#112216
>
> Thank-you to KapitanOczywisty for the implementation.
>
> cheers
> Dan
> Ack
>

Hi Dan,

When I read the RFC, I keep wondering why new syntax is needed for this. 
Isn't this a solved problem with the solution being "use a named function" ?

Might I suggest to expand the RFC to answer all or at least some of the 
below questions ?
* Why is a recursive function call something which should be supported 
at the language level for closures ?
* Was the pre-existing syntax available to solve this - named functions 
- considered ?
* Why is using named functions not considered a valid solution by the 
RFC proposers ?

As for the syntax choice: it seems like the proposed choice is largely 
arbitrary and personal to the authors to go for a "languagesy" syntax.
* Was any research done on how frequently this is expected to be used ?
* If so, does that frequency justify the need for a change at the 
language level ?
* Was any research done to find out syntax preferences from anyone other 
than the authors ?
* Was the impact of introducing (yet another) syntax level change on 
static analysis tools considered ?
     As a co-maintainer of a static analysis tool, I would have a strong 
preference for either `__CLOSURE__` or a static function on the Closure 
class as that would make the syntax "isolated" to this change, while an 
`as $fn` syntax change would mean that any analysis of the `as` keyword 
and a lot of analysis of variables will need to be adjusted to allow for 
this new syntax.
     Not necessarily a reason to change the proposal, but possibly 
something to consider.

Either way, my two pennies for whatever they are worth.

Smile,
Juliette

---

## #120527 — David Gebler — 2023-06-04T22:42:26+00:00

URL: https://externals.io/message/120518#120527 · In reply to: #120519

On Sun, Jun 4, 2023 at 12:06 PM Juliette Reinders Folmer <
php-internals_nospam@adviesenzo.nl> wrote:

> When I read the RFC, I keep wondering why new syntax is needed for this.
> Isn't this a solved problem with the solution being "use a named function"
> ?
>

I think that's a bit harsh - couldn't we say that about any limitation of
closures, or any proposed improvement to closure handling? "Just use a
named function" doesn't seem like a fair critique when the usefulness of
closures isn't in question, or the fact that people do use closures.


> Might I suggest to expand the RFC to answer all or at least some of the
> below questions ?
> * Why is a recursive function call something which should be supported
> at the language level for closures ?
>

It seems a reasonable expectation that the functional capability of
closures should as closely match named functions as possible, doesn't it?
Or at least that whatever limitations they have don't lead to runtime
surprises like the example given in the RFC.


> As for the syntax choice: it seems like the proposed choice is largely
> arbitrary and personal to the authors to go for a "languagesy" syntax.
> * Was any research done on how frequently this is expected to be used ?
> * If so, does that frequency justify the need for a change at the
> language level ?
> * Was any research done to find out syntax preferences from anyone other
> than the authors ?

* Was the impact of introducing (yet another) syntax level change on
> static analysis tools considered ?
>

I think there was a fair bit of discussion about syntax choice in the
previous thread (which was a long time ago now) but the point about impact
on static analysis tools is valid and relevant. That said, there is an
argument that it's for ecosystem tools to adapt to changes in the language,
not for the language to orient itself to the convenience of those tools.

Still, I suppose we do have a special case with static analysis tools in
particular over other stock userland libraries, because these tools in
particular serve to fill gaps in PHP's limitations as a dynamic language,
so I think your point about reconsidering syntax choice in respect of
making adaptation easier is worth the RFC authors considering further.

I think for users, the proposed choice with the "as" keyword is the most
natural. A recursive closure is probably an extremely rare thing to do
whatever way you cut it, though, so if the syntax for users is a little
uglier but it makes some other aspect such as what you've raised above
easier, I can see the justification for choosing one of the other options,
probably a constant like __CLOSURE__.

Anyway, although I can't vote, +1 from me in principle on the feature,
syntax TBC. It closes a very small gap but a gap all the same.

-Dave

---

## #120528 — drealecs@gmail.com — 2023-06-05T04:08:46+00:00

URL: https://externals.io/message/120518#120528 · In reply to: #120518

> Hi internals,
>
> I'm now opening the discussion for the Closure self-reference RFC:
> https://wiki.php.net/rfc/closure_self_reference
>
> This was previously discussed as a draft here:
> https://externals.io/message/112216#112216
>
> Thank-you to KapitanOczywisty for the implementation.
>
>
Hi Dan,

How about a keyword/variable to the current executing closure that works
also if you refactor it to a function or a method.
Just like self for a class we can have a keyword like fnself or a variable
like $fnself that is automatically available inside the body.
For a closure it would be the closure itself while for a function / method
it can be even just a little syntactic sugar to functionName(...) /
self::methodName(...) (not using polymorphism intentionally).
Maybe we decide not to implement this right now for functions/methods but
we can at least choose a name that has a wider meaning.

As we are talking references, I think there should be a mention in the RFC
about how GC will (not?) be impacted?
Is the closure reference count incremented just when the Closure execution
starts, with no impact on GC?


Regards,
Alex

---

## #120534 — Timo Tijhof — 2023-06-06T14:05:55+00:00

URL: https://externals.io/message/120518#120534 · In reply to: #120528

On Mon, 5 Jun 2023 at 05:09, Alexandru Pătrănescu <drealecs@gmail.com>
wrote:

>
> How about a keyword/variable to the current executing closure that works
> also if you refactor it to a function or a method.
> Just like self for a class we can have a keyword like fnself [..]


This seems quite appealing to me, and is imho  more idiomatic and ergonomic
than the other proposals.

Keywords naturally avoid conflicts with user variables, and remove the need
for each author to pick a name for their closure and the inevitable
preferences, automation, and disagreements that will arise from that.

On the other hand, we've seen from *match()* how disruptive a new keyword
can be as they clash as well, with function names instead of variables.
Building on an existing keyword or soft-reserved naming convention would
avoid that.

In terms of global constants, we have double underscores which is in the
proposal already but feels unnatural as others have indicated already.

In terms of local constants, I believe we authors generally prefer
uppercase names, and we have one built-in special constant that's
lowercase: *self::class*.

Perhaps *self::fn* or *self::callee*?

The latter borrows the closure terminology form JavaScript
(arguments.callee, which does the same thing).

--
Timo Tijhof
https://timotijhof.net/

---

## #120535 — Bruce Weirdan — 2023-06-06T14:26:08+00:00

URL: https://externals.io/message/120518#120535 · In reply to: #120518

> I'm now opening the discussion for the Closure self-reference RFC:
> https://wiki.php.net/rfc/closure_self_reference

Looking at the syntax options on the RFC page, the following
explanation is not clear to me:

> * De-anonymize the function. This has a large aesthetic downside of appearing to create the closure variable in the scope that the closure is declared in, rather than internal to the closure scope.

Does this mean that the variable wouldn't actually be created in the
enclosing scope, but someone may *think* it would?


-- 
  Best regards,
      Bruce Weirdan                                     mailto:weirdan@gmail.com

---

## #120537 — Erick de Azevedo Lima — 2023-06-06T21:51:31+00:00

URL: https://externals.io/message/120518#120537 · In reply to: #120535

Hello you all.

As closures are objects, I'd be ok with $this->__invoke(), but it's not
possible because closures can be bound to other contexts.
From the proposed solutions, the one that makes more sense to me is the
__CLOSURE__, because not only it does not need
the boilerplate that can be confusing about the usage of "use/as" but it
also shouts out for the ones reading the code that this
function is calling itself.

Best regards,
Erick

Em ter., 6 de jun. de 2023 às 11:26, Bruce Weirdan <weirdan@gmail.com>
escreveu:

> 
> > […]
>
> Looking at the syntax options on the RFC page, the following
> explanation is not clear to me:
>
> > […]
> appearing to create the closure variable in the scope that the closure is
> declared in, rather than internal to the closure scope.
>
> Does this mean that the variable wouldn't actually be created in the
> enclosing scope, but someone may *think* it would?
>
>
> --
>   Best regards,
>       Bruce Weirdan                                     mailto:
> weirdan@gmail.com
>
> --
> 
> To unsubscribe, visit: https://www.php.net/unsub.php

---

## #120550 — Stephen Reay — 2023-06-09T05:59:27+00:00

URL: https://externals.io/message/120518#120550 · In reply to: #120518

> 
> 
> Hi internals,
> 
> I'm now opening the discussion for the Closure self-reference RFC:
> https://wiki.php.net/rfc/closure_self_reference
> 
> This was previously discussed as a draft here:
> https://externals.io/message/112216#112216
> 
> Thank-you to KapitanOczywisty for the implementation.
> 
> cheers
> Dan
> Ack
> 
> -- 
> 
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi Dan,

I quite like this idea, but, to (ab)use the analogy, the syntax bike shed definitely needs a few more sample tins.

The various syntax choices that introduce a new variable all seem like they can easily lead to developer confusion about where each of the two variables are actually defined and what is valid.. I can see plenty of “$closure = fn() as $closure => ….;` just because people are unsure.


Is there a syntax issue with e.g. `fn::self` / `function::self` for this? I realise this is mostly just a variation on `Closure::current()` but it “feels” a bit more natural, and has the added benefit that it *could* be extended to return a closure of **any** function, including regular named methods/functions etc in a later RFC, if there’s demand for it.



Cheers

Stephen
