Re: [RFC] Arrow functions / short closures

This is only part of a thread. view whole thread
  105273
April 14, 2019 16:52 nikita.ppv@gmail.com (Nikita Popov)
On Mon, Apr 8, 2019 at 4:06 PM Nikita Popov ppv@gmail.com> wrote:

> On Wed, Mar 13, 2019 at 4:56 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 >> > > Heads up: I plan to start voting on this RFC tomorrow if nothing new comes > up. > > Most of the discussion was (as expected) about the choice of syntax. > Ultimately I think there are many reasonable choices we can make here, but > we should stick to a specific proposal for the purposes of the RFC vote. > None of the given arguments convinced me that some other syntax is > *strictly* better than the proposed fn($x, $y) => $x*$y -- it's more a > matter of some choices being slightly better in one case and slightly worse > in another. My personal runner-up would be \($x, $y) => $x*$y, but I > suspect that there are some people who are more strongly biased against > "sigil salad" than I am... > > Nikita >
So, there's been quite a bit of extra discussion here... unfortunately I can't say that it really clarified anything, we're still circling around different syntax choices, with the main contenders being fn, \ and ==>. fn($x) => $x fn($x, $y) => $x*$y \$x => $x \($x, $y) => $x*$y $x ==> $x ($x, $y) ==> $x*$y I think the main qualities of these possibilities are: * Implementation complexity: fn and \ are easy, ==> is hard (lexer hack). * Availability of reduced syntax: \ an ==> have a special single-argument syntax, fn doesn't. * Obviousness/readability: fn and ==> are obvious, while \ is not. Especially \$x => $x looks quite obscure to the uninitiated (is that a variable escape, like it would be in strings?) At this point I'm considering to either a) move forward with fn() as the choice I'd consider most likely to gather a consensus or b) have a secondary three-way vote between these three syntax choices. Nikita
  105282
April 15, 2019 11:24 bjorn.x.larsson@telia.com (=?UTF-8?Q?Bj=c3=b6rn_Larsson?=)
Den 2019-04-14 kl. 18:52, skrev Nikita Popov:
> On Mon, Apr 8, 2019 at 4:06 PM Nikita Popov ppv@gmail.com> wrote: > >> On Wed, Mar 13, 2019 at 4:56 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 >>> >> Heads up: I plan to start voting on this RFC tomorrow if nothing new comes >> up. >> >> Most of the discussion was (as expected) about the choice of syntax. >> Ultimately I think there are many reasonable choices we can make here, but >> we should stick to a specific proposal for the purposes of the RFC vote. >> None of the given arguments convinced me that some other syntax is >> *strictly* better than the proposed fn($x, $y) => $x*$y -- it's more a >> matter of some choices being slightly better in one case and slightly worse >> in another. My personal runner-up would be \($x, $y) => $x*$y, but I >> suspect that there are some people who are more strongly biased against >> "sigil salad" than I am... >> >> Nikita >> > So, there's been quite a bit of extra discussion here... unfortunately I > can't say that it really clarified anything, we're still circling around > different syntax choices, with the main contenders being fn, \ and ==>. > > fn($x) => $x > fn($x, $y) => $x*$y > > \$x => $x > \($x, $y) => $x*$y > > $x ==> $x > ($x, $y) ==> $x*$y > > I think the main qualities of these possibilities are: > > * Implementation complexity: fn and \ are easy, ==> is hard (lexer hack). > * Availability of reduced syntax: \ an ==> have a special single-argument > syntax, fn doesn't. > * Obviousness/readability: fn and ==> are obvious, while \ is not. > Especially \$x => $x looks quite obscure to the uninitiated (is that a > variable escape, like it would be in strings?) > > At this point I'm considering to either a) move forward with fn() as the > choice I'd consider most likely to gather a consensus or b) have a > secondary three-way vote between these three syntax choices. > > Nikita Hi,
Even if a consensus wasn't reached I feel that there has been quite a constructive discussion, where the pros and cons were drilled down for the syntax alternatives at hand. So having no voting rights myself, but alternative B for voting looks ok in my eyes. One could ask having three alternatives or two? OTOH, those three alternatives are now on the table and nothing else, so all three. But if implementation of ==> are much to overwhelming, only two. r//Björn L
  105283
April 15, 2019 11:48 benjamin.morel@gmail.com (Benjamin Morel)
Even though I was originally hoping for something closer to JS syntax,
considering Nikita's summary it looks like the best contender is still
fn(), as originally proposed.
At least it looks like a function indeed, to the uninitiated.

So FWIW, I think that a vote for the fn() syntax only still makes sense.
The risk with the 2 or 3 options is never being able to reach a concensus:
is a relative majority or an absolute majority for one of the syntaxes
acceptable, or are you required by the RFC process to get a 2/3 majority
for this vote as well? If so, considering the discussion so far, I think
this will be hard to achieve with 2 choices, let alone with 3.

- Ben
  105285
April 15, 2019 12:04 bjorn.x.larsson@telia.com (=?UTF-8?Q?Bj=c3=b6rn_Larsson?=)
Den 2019-04-15 kl. 13:48, skrev Benjamin Morel:
> Even though I was originally hoping for something closer to JS syntax, > considering Nikita's summary it looks like the best contender is still > fn(), as originally proposed. > At least it looks like a function indeed, to the uninitiated. > > So FWIW, I think that a vote for the fn() syntax only still makes > sense. The risk with the 2 or 3 options is never being able to reach a > concensus: is a relative majority or an absolute majority for one of > the syntaxes acceptable, or are you required by the RFC process to get > a 2/3 majority for this vote as well? If so, considering the > discussion so far, I think this will be hard to achieve with 2 > choices, let alone with 3. > > - Ben
If it lands in a secondary three way vote I would assume it's the vote getting the most votes. Otherwise the RFC could land in a limbo, getting yes on feature but no on syntax. Good to get assumption confirmed though... r//Björn L
  105311
April 17, 2019 14:03 larry@garfieldtech.com ("Larry Garfield")
On Mon, Apr 15, 2019, at 6:48 AM, Benjamin Morel wrote:
> Even though I was originally hoping for something closer to JS syntax, > considering Nikita's summary it looks like the best contender is still > fn(), as originally proposed. > At least it looks like a function indeed, to the uninitiated. > > So FWIW, I think that a vote for the fn() syntax only still makes sense. > The risk with the 2 or 3 options is never being able to reach a concensus: > is a relative majority or an absolute majority for one of the syntaxes > acceptable, or are you required by the RFC process to get a 2/3 majority > for this vote as well? If so, considering the discussion so far, I think > this will be hard to achieve with 2 choices, let alone with 3. > > - Ben
I don't think the wiki currently supports it, but that's exactly what ranked choice voting is for. :-) --Larry Garfield
  105284
April 15, 2019 11:59 php-lists@koalephant.com (Stephen Reay)
> On 14 Apr 2019, at 23:52, Nikita Popov ppv@gmail.com> wrote: > > On Mon, Apr 8, 2019 at 4:06 PM Nikita Popov ppv@gmail.com> wrote: > >> On Wed, Mar 13, 2019 at 4:56 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 >>> >> >> Heads up: I plan to start voting on this RFC tomorrow if nothing new comes >> up. >> >> Most of the discussion was (as expected) about the choice of syntax. >> Ultimately I think there are many reasonable choices we can make here, but >> we should stick to a specific proposal for the purposes of the RFC vote. >> None of the given arguments convinced me that some other syntax is >> *strictly* better than the proposed fn($x, $y) => $x*$y -- it's more a >> matter of some choices being slightly better in one case and slightly worse >> in another. My personal runner-up would be \($x, $y) => $x*$y, but I >> suspect that there are some people who are more strongly biased against >> "sigil salad" than I am... >> >> Nikita >> > > So, there's been quite a bit of extra discussion here... unfortunately I > can't say that it really clarified anything, we're still circling around > different syntax choices, with the main contenders being fn, \ and ==>. > > fn($x) => $x > fn($x, $y) => $x*$y > > \$x => $x > \($x, $y) => $x*$y > > $x ==> $x > ($x, $y) ==> $x*$y > > I think the main qualities of these possibilities are: > > * Implementation complexity: fn and \ are easy, ==> is hard (lexer hack). > * Availability of reduced syntax: \ an ==> have a special single-argument > syntax, fn doesn't. > * Obviousness/readability: fn and ==> are obvious, while \ is not. > Especially \$x => $x looks quite obscure to the uninitiated (is that a > variable escape, like it would be in strings?) > > At this point I'm considering to either a) move forward with fn() as the > choice I'd consider most likely to gather a consensus or b) have a > secondary three-way vote between these three syntax choices. > > Nikita
As someone without voting rights (and thus you can take this with a grain of salt), given what you’ve highlighted I believe your option (a) is the obvious one: You said yourself, that `==>` is a more complex/hard implementation (which is bad) and that `\` is non obvious/obscure, and (IMO) it’s worse as far as readability goes. As I’ve said before, I expect to use this feature (if it passes) very little if at all, but I still appreciate that `fn()...` keeps reasonably-familiar/obvious syntax, because even if I choose not to write using this feature, I’ll invariably have to read someone else’s code that does use it. Cheers Stephen
  105305
April 17, 2019 09:23 bjorn.x.larsson@telia.com (=?UTF-8?Q?Bj=c3=b6rn_Larsson?=)
Den 2019-04-14 kl. 18:52, skrev Nikita Popov:
> On Mon, Apr 8, 2019 at 4:06 PM Nikita Popov ppv@gmail.com> wrote: > >> On Wed, Mar 13, 2019 at 4:56 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 >>> >> Heads up: I plan to start voting on this RFC tomorrow if nothing new comes >> up. >> >> Most of the discussion was (as expected) about the choice of syntax. >> Ultimately I think there are many reasonable choices we can make here, but >> we should stick to a specific proposal for the purposes of the RFC vote. >> None of the given arguments convinced me that some other syntax is >> *strictly* better than the proposed fn($x, $y) => $x*$y -- it's more a >> matter of some choices being slightly better in one case and slightly worse >> in another. My personal runner-up would be \($x, $y) => $x*$y, but I >> suspect that there are some people who are more strongly biased against >> "sigil salad" than I am... >> >> Nikita >> > So, there's been quite a bit of extra discussion here... unfortunately I > can't say that it really clarified anything, we're still circling around > different syntax choices, with the main contenders being fn, \ and ==>. > > fn($x) => $x > fn($x, $y) => $x*$y > > \$x => $x > \($x, $y) => $x*$y > > $x ==> $x > ($x, $y) ==> $x*$y > > I think the main qualities of these possibilities are: > > * Implementation complexity: fn and \ are easy, ==> is hard (lexer hack). > * Availability of reduced syntax: \ an ==> have a special single-argument > syntax, fn doesn't. > * Obviousness/readability: fn and ==> are obvious, while \ is not. > Especially \$x => $x looks quite obscure to the uninitiated (is that a > variable escape, like it would be in strings?) > > At this point I'm considering to either a) move forward with fn() as the > choice I'd consider most likely to gather a consensus or b) have a > secondary three-way vote between these three syntax choices. > > Nikita
Hi again , I came to think on BC impact of fn() syntax. The RFC mentions 12 matches and 1 in namespaces. Should one conclude that the BC impact is low or is their other aspects to consider? I myself uses fn as a dummy function name when writing "test" code. r//Björn L
  105306
April 17, 2019 10:17 nikita.ppv@gmail.com (Nikita Popov)
On Wed, Apr 17, 2019 at 11:23 AM Björn Larsson larsson@telia.com>
wrote:

> Den 2019-04-14 kl. 18:52, skrev Nikita Popov: > > On Mon, Apr 8, 2019 at 4:06 PM Nikita Popov ppv@gmail.com> > wrote: > > > >> On Wed, Mar 13, 2019 at 4:56 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 > >>> > >> Heads up: I plan to start voting on this RFC tomorrow if nothing new > comes > >> up. > >> > >> Most of the discussion was (as expected) about the choice of syntax. > >> Ultimately I think there are many reasonable choices we can make here, > but > >> we should stick to a specific proposal for the purposes of the RFC vote. > >> None of the given arguments convinced me that some other syntax is > >> *strictly* better than the proposed fn($x, $y) => $x*$y -- it's more a > >> matter of some choices being slightly better in one case and slightly > worse > >> in another. My personal runner-up would be \($x, $y) => $x*$y, but I > >> suspect that there are some people who are more strongly biased against > >> "sigil salad" than I am... > >> > >> Nikita > >> > > So, there's been quite a bit of extra discussion here... unfortunately I > > can't say that it really clarified anything, we're still circling around > > different syntax choices, with the main contenders being fn, \ and ==>. > > > > fn($x) => $x > > fn($x, $y) => $x*$y > > > > \$x => $x > > \($x, $y) => $x*$y > > > > $x ==> $x > > ($x, $y) ==> $x*$y > > > > I think the main qualities of these possibilities are: > > > > * Implementation complexity: fn and \ are easy, ==> is hard (lexer > hack). > > * Availability of reduced syntax: \ an ==> have a special > single-argument > > syntax, fn doesn't. > > * Obviousness/readability: fn and ==> are obvious, while \ is not.. > > Especially \$x => $x looks quite obscure to the uninitiated (is that a > > variable escape, like it would be in strings?) > > > > At this point I'm considering to either a) move forward with fn() as the > > choice I'd consider most likely to gather a consensus or b) have a > > secondary three-way vote between these three syntax choices. > > > > Nikita > > Hi again , > > I came to think on BC impact of fn() syntax. The RFC mentions > 12 matches and 1 in namespaces. Should one conclude that > the BC impact is low or is their other aspects to consider? I > myself uses fn as a dummy function name when writing > "test" code. >
Yes, the impact is expected to be pretty much limited to my https://github.com/nikic/iter library (where I will rename the namespace in the upcoming 2.0 version) and test code. Nikita
  105312
April 17, 2019 14:14 larry@garfieldtech.com ("Larry Garfield")
On Sun, Apr 14, 2019, at 11:52 AM, Nikita Popov wrote:

> So, there's been quite a bit of extra discussion here... unfortunately I > can't say that it really clarified anything, we're still circling around > different syntax choices, with the main contenders being fn, \ and ==>. > > fn($x) => $x > fn($x, $y) => $x*$y > > \$x => $x > \($x, $y) => $x*$y > > $x ==> $x > ($x, $y) ==> $x*$y > > I think the main qualities of these possibilities are: > > * Implementation complexity: fn and \ are easy, ==> is hard (lexer hack). > * Availability of reduced syntax: \ an ==> have a special single-argument > syntax, fn doesn't. > * Obviousness/readability: fn and ==> are obvious, while \ is not. > Especially \$x => $x looks quite obscure to the uninitiated (is that a > variable escape, like it would be in strings?) > > At this point I'm considering to either a) move forward with fn() as the > choice I'd consider most likely to gather a consensus or b) have a > secondary three-way vote between these three syntax choices. > > Nikita
I was under the impression from your earlier comments that ==> made the lexer too unhappy to even consider. Is that not the case? From a usability POV, I think ==> has the edge; it's reasonably self-documenting and has a short-circuit version that is still highly readable and not confusing. It also fits the "think of it as an expression not a function call" mindset, which is important. The only downside is the implementation complexity. I think you have final call on whether that would be too-ugly implementation-wise. If it doesn't make the lexer too unhappy ==> is my preference, I think. \$x I'd probably get used to, even if it is a bit ugly. fn() is the "safe" option: Most verbose but keeps the lexer happy. --Larry Garfield
  105315
April 18, 2019 08:15 bjorn.x.larsson@telia.com (=?UTF-8?Q?Bj=c3=b6rn_Larsson?=)
Den 2019-04-17 kl. 16:14, skrev Larry Garfield:
> On Sun, Apr 14, 2019, at 11:52 AM, Nikita Popov wrote: > >> So, there's been quite a bit of extra discussion here... unfortunately I >> can't say that it really clarified anything, we're still circling around >> different syntax choices, with the main contenders being fn, \ and ==>. >> >> fn($x) => $x >> fn($x, $y) => $x*$y >> >> \$x => $x >> \($x, $y) => $x*$y >> >> $x ==> $x >> ($x, $y) ==> $x*$y >> >> I think the main qualities of these possibilities are: >> >> * Implementation complexity: fn and \ are easy, ==> is hard (lexer hack). >> * Availability of reduced syntax: \ an ==> have a special single-argument >> syntax, fn doesn't. >> * Obviousness/readability: fn and ==> are obvious, while \ is not. >> Especially \$x => $x looks quite obscure to the uninitiated (is that a >> variable escape, like it would be in strings?) >> >> At this point I'm considering to either a) move forward with fn() as the >> choice I'd consider most likely to gather a consensus or b) have a >> secondary three-way vote between these three syntax choices. >> >> Nikita > I was under the impression from your earlier comments that ==> made the lexer too unhappy to even consider. Is that not the case? > > From a usability POV, I think ==> has the edge; it's reasonably self-documenting and has a short-circuit version that is still highly readable and not confusing. It also fits the "think of it as an expression not a function call" mindset, which is important. The only downside is the implementation complexity. I think you have final call on whether that would be too-ugly implementation-wise. > > If it doesn't make the lexer too unhappy ==> is my preference, I think. \$x I'd probably get used to, even if it is a bit ugly. fn() is the "safe" option: Most verbose but keeps the lexer happy. > > --Larry Garfield
Spot on I would say! The comment "think of it as an expression not a function call" captures my own hesitation for the fn() syntax quite well. Anyway it's in voting, so glad we finally got this truck moving :) r//Björn L