Re: [PHP-DEV] [RFC] Arrow functions / short closures

This is only part of a thread. view whole thread
  104731
March 15, 2019 09:01 drealecs@gmail.com (=?UTF-8?Q?Alexandru_P=C4=83tr=C4=83nescu?=)
Hi,

To start with, I personally understand why a prefix character is needed
before parenthesis to make the parser simpler. I would like another simpler
option but will have to investigate more on this.

My question would be: whatever syntax we are going to use that has arrow
syntax, let's say *$f = \($x) => $x * 2;* are we going to also support the
arrow block version?:
*$f = \($x) => {*
*    // more operations that will have better visible on multi-line*

*    return $x * 2;*
*}*

This is present in other languages and was thinking that we could have it
in PHP also.

Regards,
Alex


On Wed, Mar 13, 2019 at 5:57 PM Nikita Popov ppv@gmail.com> wrote:

> Hi internals, > > Motivated by the recent list comprehensions RFC, I think it's time we took > another look at short closures: > > https://wiki.php.net/rfc/arrow_functions_v2 > > This is based on a previous (withdrawn) proposal by Levi & Bob. It uses the > syntax > > fn($x) => $x * $multiplier > > and implicit by-value variable binding. This example is roughly equivalent > to: > > function($x) use($multiplier) { return $x * $multiplier; } > > The RFC contains a detailed discussion of syntax choices and binding modes. > > Regards, > Nikita >
  104732
March 15, 2019 09:30 rowan.collins@gmail.com (Rowan Collins)
On Fri, 15 Mar 2019 at 09:01, Alexandru Pătrănescu <drealecs@gmail.com>
wrote:

> My question would be: whatever syntax we are going to use that has arrow > syntax, let's say *$f = \($x) => $x * 2;* are we going to also support the > arrow block version?: > *$f = \($x) => {* > * // more operations that will have better visible on multi-line* > > * return $x * 2;* > *}* >
See "Future Scope" in the RFC:
> This feature is omitted in this RFC, because the value-proposition of this syntax is much smaller: Once you have multiple statements, the
relative overhead of the conventional closure syntax becomes small. We shouldn't pick a syntax that rules it out, but it can be added later, with a separate RFC to discuss the benefits and details. Regards, -- Rowan Collins [IMSoP]
  104738
March 15, 2019 10:10 nikita.ppv@gmail.com (Nikita Popov)
On Fri, Mar 15, 2019 at 10:31 AM Rowan Collins collins@gmail.com>
wrote:

> On Fri, 15 Mar 2019 at 09:01, Alexandru Pătrănescu <drealecs@gmail.com> > wrote: > > > My question would be: whatever syntax we are going to use that has arrow > > syntax, let's say *$f = \($x) => $x * 2;* are we going to also support > the > > arrow block version?: > > *$f = \($x) => {* > > * // more operations that will have better visible on multi-line* > > > > * return $x * 2;* > > *}* > > > > > See "Future Scope" in the RFC: > > > This feature is omitted in this RFC, because the value-proposition of > this syntax is much smaller: Once you have multiple statements, the > relative overhead of the conventional closure syntax becomes small. > > We shouldn't pick a syntax that rules it out, but it can be added later, > with a separate RFC to discuss the benefits and details. >
It might be worth giving some consideration to the possibility of introducing this syntax already in this RFC. The main problem with punting this off for later is that it may be necessary to refactor closures between the short and the long form regularly: You need an extra statement in the closure? You have to switch closure types, and also not forget to write our the use() list this time. On the other hand, allowing a block body for the closure does add a number of complications to this proposal: 1. Syntax choice. Given the fn() syntax, we could go for either fn() {} or fn() => {}. 2. By-ref binding: While by-reference binding is not useful for single-expression closures, there will be cases where it's needed for block closures. We will also need to choose a syntax to opt-in to by-reference binding. The RFC suggests use(&), which is somewhat non-great. 3. Determining bound variables. For single-expression closures we can get away with binding all variables that are used inside the closure. Writing something like fn() $a = $b might cause an unnecessary binding of $a, but it's also a very contrived situation. For block closures performing assignments inside the closure will be much more common and will need some more consideration to avoid unnecessary bindings. Regards, Nikita
  104740
March 15, 2019 10:50 rowan.collins@gmail.com (Rowan Collins)
On Fri, 15 Mar 2019 at 10:10, Nikita Popov ppv@gmail.com> wrote:

> It might be worth giving some consideration to the possibility of > introducing this syntax already in this RFC. The main problem with punting > this off for later is that it may be necessary to refactor closures between > the short and the long form regularly: You need an extra statement in the > closure? You have to switch closure types, and also not forget to write our > the use() list this time. >
I know I'm not necessarily in the majority, here, but to me, that's a feature not a bug: short closures should not be a replacement for every anonymous function, they should be for those cases where you have a really simple expression. At some point, you should be saying "this is now too long for a short closure, it needs a clearer definition", and "more than one expression or statement" is as good a heuristic for that as you're likely to get. I also have strong reservations about generalising automatic binding to full function bodies, because it fundamentally changes the way variable scope works in the language: right now, $foo is always local to a function, unless *explicitly* listed as a parameter, imported with "global", or captured with "use". That's a lot simpler than the scoping rules of a lot of other languages, and it's a guarantee we shouldn't break lightly. I'm willing to be convinced - or simply "out-voted" - on these points, but I think they deserve their own discussion. I was shot down on chat the other day for a naive remark that capturing a large number of variables in a closure would be "doing it wrong"; I'd love to see examples of where this is useful / necessary, and a new RFC would be the perfect place for someone to put those. That could mean another RFC proposed immediately after this one passes, and the feature arriving in the same PHP version, but I don't think we need to merge the two discussions - as long as we keep the possibility in mind when choosing a base syntax. Regards, -- Rowan Collins [IMSoP]