RFC [Discussion]: Closure self-reference

php.internals

Dan Ackroyd

3 years ago
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

Unnamed Person

3 years ago
On 3-6-2023 21:11, Dan Ackroyd wrote:
> 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

David Gebler

3 years ago
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

Alexandru Pătrănescu

3 years ago
On Sat, Jun 3, 2023, 21:11 Dan Ackroyd <Danack@basereality.com> wrote:
> 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

Timo Tijhof

3 years ago
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/

Weirdan

3 years ago
On Sat, Jun 3, 2023 at 9:11 PM Dan Ackroyd <Danack@basereality.com> wrote:
> 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

Erick de Azevedo Lima

3 years ago
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:

Stephen Reay

3 years ago
> On 4 Jun 2023, at 02:11, Dan Ackroyd <Danack@basereality.com> wrote: > > 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 > > -- > PHP Internals - PHP Runtime Development Mailing List > 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