-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Update Short Closures spec to remove space after fn
keyword
#53
Conversation
d7c8eca
to
5601f11
Compare
Per the accepted [Arrow Functions RFC](https://wiki.php.net/rfc/arrow_functions_v2) and [per its author](https://www.reddit.com/r/PHP/comments/fctb18/comment/fjd9u6a/), short closures were intended to be written without a space after the `fn` keyword. This is also the default formatting enforced by PhpStorm. PHP-CS-Fixer was an outlier which incorrectly enforced spacing after the `fn` keyword using the same setting as for the `function` keyword. This was a bug and has been corrected with the addition of a separate `closure_fn_spacing` setting (though this setting still defaults to `one` for backwards compatibility - the plan was to [change it to enforce no space](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/b577444c38b61f2fdc32cd0a4685bd595be391b7/src/Fixer/FunctionNotation/FunctionDeclarationFixer.php#L235) in the next major 4.0 version). But the current PER coding style spec may get in the way of this plan. Since the primary goal of arrow functions is to avoid the verbosity of anonymous functions, requiring a space after the `fn` keyword is a step backwards, and also doesn't align with general usage promoted by PhpStorm as well as the accepted PHP RFC and documentation. The section on Short Closures was not added until the 17th of July by php-fig#17, which was after the 1.0.0 spec was approved/released on June 9, so I'm hoping it's not too late to correct it.
5601f11
to
6deac37
Compare
I quite hate the extra space, so if we can change the rule to not have it (the currently published version doesn't mention it at all, so nothing is finalized yet) I am fully on board. Hell, I'd get rid of the space on long-closures too, if we could. 😄 |
Independently of personal tastes, this introduces an inconsistency in the standard with long closures. As this is supposed to be a coding style standard, consistency is key, so I'm not sure this is a good idea.... |
@jrfnl Arrow functions have a unique syntax from full closures, aimed at conciseness, so I don't think it's inconsistent for them to have their own spacing rule. |
Is there anything else I can do to move this forward?
No, I give pull requests that change the spec two full weeks in case anyone
wants to weigh in.
…On Mon, Nov 21, 2022 at 1:21 PM Theodore Brown ***@***.***> wrote:
Is there anything else I can do to move this forward?
—
Reply to this email directly, view it on GitHub
<#53 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAHV6O6GGDSPYXOQ423HKQDWJPRT7ANCNFSM6AAAAAAR4VZLDQ>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
Note: I also checked the PHP Prettier plugin and found that it, like PhpStorm, formats arrow functions without a space after the |
Looks good to me, one thing that pops out at me is the following is incorrect:
for example consider something like https://3v4l.org/SRSVo: foo(fn(string $baz) => "Input: $baz");
// vs
foo( fn(string $baz) => "Input: $baz"); but this can be sorted out in a separate PR |
Can we actually make some research on how arrow functions are used in the wild? PSR-12 team conducted a survey, gathering votes from 142 people including 17 project representatives. For this PR, I can see 4 people, including one being against this change.
Sure, except for completely niche projects like Symfony, Laravel, PHPUnit, Composer, Magento, Doctrine, PHPStan, Flysystem, Laminas, Phalcon, PHP-CS-Fixer, Rector, Spatie, phpDocumentor... Also, I did a quick code search on GitHub:
You mean PHP documentation? It doesn't seem to care about any coding style in the slightest (screenshot from https://www.php.net/manual/en/functions.anonymous.php).
So defaults in PHP-CS-Fixer, which doesn't match your taste, are just incorrect, but bringing up defaults in PhpStorm and Prettier is a valid point in discussion?
That's actually the only argument that makes sense to me. However, the RFC author did allow a space after the |
Out of that list, Symfony, PHPUnit, Composer Packagist, Magento, Flysystem, Phalcon, PHP-CS-Fixer, and Spatie are all using PHP-CS-Fixer, which until the latest release (v3.13) didn't allow differentiating between Another project in your list (Laminas) does not appear to enforce an arrow function spacing rule - some Other well-known projects such as Psalm enforce having no space after the
That screenshot isn't related to arrow functions (I did submit a PR to fix that inconsistency, though). The official Arrow Functions documentation examples do use consistent formatting which matches the accepted RFC.
My point was that PHP-CS-Fixer's defaults didn't match other popular tools. Now that PHP-CS-Fixer allows configuring spacing for Since there hasn't yet been a released PSR standard for To summarize, the following arguments could be used to favor a space after
On the other hand, the following points favor no space after
|
They did have the option, it's as simple as
This option was released almost a month ago, and none of the big projects I brought up changed it so far. Why do you think that all of these projects have been forced to use this spacing by PHP-CS-Fixer? What makes you sure that any of these projects wants to change that? All of them were free to format their code however they want. They've chosen. They can change it whenever they want, yet they don't.
It wasn't supposed to be related to arrow functions, it was supposed to show my point: PHP documentation doesn't care about any coding style, so bringing it up in a discussion about coding style makes no sense.
PhpStorm may be used in far more projects, but not as a formatter. PhpStorm can't even be used to enforce consistent formatting, as you can't use it in your CI. And for Prettier we have numbers: 1.5k stars for Prettier, 11.5k stars for PHP-CS-Fixer. So my question remains: why do you call defaults in PHP-CS-Fixer “incorrect”, but bring up defaults in PhpStorm and Prettier is a valid point in discussion?
verbose: containing more words than necessary (Merriam-Webster) Sorry for taking apart your words, but I think there's a point there: having more whitespace is something different than having more words, and it makes code easier to read for some people. You don't need to add any spaces around binary operators, after the type colon, or between function arguments, yet you do for some reason. You could probably even format most of your PHP files to be one line to reduce “verbosity”.
I agree with the point about the RFC. The documentation argument doesn't make any sense though, for the reason stated above. There is anything but coding style consistency in PHP documentation.
You're right, my bad with Laminas. Also, I'm not saying that nobody prefers this style, Nette seems to use it too. My point with bringing up these projects is that it's just false that
|
You vastly under-estimate the effort involved in changing coding standards on a large project. IME, it can take months just to agree to do it, to say nothing of actually making the change. @jrmajor is correct that we should be informed by research, however. Which he has, graciously, done for us. If we take the screenshot from GitHub at face value, it tells us that while It's also a valid observation that it seems very likely that many/most of those projects didn't make an active, deliberate decision. They just turned on php-cs-fixer, or Prettier, or whatever tool and left it at its defaults, or made only one or two changes. That's true for both styles, probably. So if we make a statement at all, it's going to disrupt about the same amount of code either way. And odds are, those people will upgrade their formatting tool at some point in the future, it will say "now using PER-CS 1.1", and flag a bunch of things. Users will roll their eyes, push "yes", and move on with their lives. So our decision should be based on internal consistency within the spec, and on what is most ergonomic (which is admittedly hard to get any objective data about in this case). The popularity argument is basically a wash either way. |
Even if it wasn't as deliberate decision, which I doubt, there is nothing suggesting that these projects want to change that. And there's high chance they won't, for the exact reason you provided.
I find the way you rounded these percentages unfair. Anyway, I've taken this screenshot only to show that even the simplest research one can do reveals that the claim about the “general usage” is false. For more accurate results, I've analysed 1000 most popular Composer packages using https://github.com/nikic/popular-package-analysis and this script. Here are the results:
Which is in line with the fact that most popular tools in all categories I could think of also use In the end, we can all live with whatever ends up being included in PER CS. My main complaint isn't as much about the |
As things were, the `WordPress.WhiteSpace.ControlStructureSpacing` sniff was being _abused_ to also check the formatting of function declaration statements, while it really isn't suitable for this. There have been numerous issues regarding this and various "plaster on the wound" fixes have been made previously. This PR is intended to fix the problem once and for all in a more proper fashion. The checks which were previously done by the `WordPress.WhiteSpace.ControlStructureSpacing` sniff consisted of the following: * Exactly one space after the `function` keyword (configurable for closures). * No space between the function _name_ and the open parenthesis. * Exactly one space after the open parenthesis. * Exactly one space before the close parenthesis. * Exactly one space before the open brace/after the close parenthesis. The above didn't take return type declarations into account properly, would run into problems with function declarations which didn't have an open brace, such as `abstract` functions or interface functions (also see 2204), and handling multi-line function declarations was undefined territory. It also led to: * Duplicate messages - the `ControlStructureSpacing` sniff reporting things also reported by the `Squiz.Functions.FunctionDeclarationArgumentSpacing` sniff or by the `Generic.WhiteSpace.LanguageConstructSpacing` sniff. * Unclear messages [1] - messages were often thrown on the `function` keyword, while the problem was further down the line. * Unclear messages [2] - messages would refer to control structures instead of functions and would otherwise not always be clear. This commit: * Removes all code related to checking function declarations from the `WordPress.WhiteSpace.ControlStructureSpacing` sniff. Includes removing the tests which were specific to function declarations. This effectively reverts the function related changes in PRs 417, 432, 440, 463, 1319, 1837 in so far as those touched the `ControlStructureSpacing` sniff. * Adds the `Squiz.Functions.MultiLineFunctionDeclaration` sniff to the `Core` ruleset to do those checks instead. The change as currently proposed has been extensively researched and tested and should provide a smooth switch over. Notes about the ruleset changes: * The `Squiz.Functions.FunctionDeclarationArgumentSpacing.SpacingBeforeClose` code was previously silenced to prevent duplicate messages, but can now be re-enabled as we'll defer to that sniff for the spacing on the inside of the parentheses. * The `Squiz.Functions.MultiLineFunctionDeclaration` sniff, by default, expects the opening brace for named functions on the line _after_ the declaration and for closures, it expects the opening brace on the _same_ line as the closure declaration. WPCS expects the opening brace on the _same_ line as the function declaration in both cases and enforces this via the `Generic.Functions.OpeningFunctionBraceKernighanRitchie` sniff (which is also used by the `Squiz.Functions.MultiLineFunctionDeclaration` sniff for the closure check). The ruleset now contains three error code exclusions to bypass the "brace on new line for named functions" checks. * As the opening brace for closures is enforced to be on the same line, we can let the new Squiz sniff handle this. To that end the `checkClosures` property for the `Generic.Functions.OpeningFunctionBraceKernighanRitchie` sniff is set to `false` to prevent duplicate messages for the same. * To prevent duplicate messages about code after the open brace for named functions, the `Generic.Functions.OpeningFunctionBraceKernighanRitchie.ContentAfterBrace` code has to be silenced. We cannot silence the same error code for the Squiz sniff as that would also silence the notice for closures, so silencing it for the `OpeningFunctionBraceKernighanRitchie` sniff, which now only handles named functions, is the only option, but should prevent the duplicate messages. * Additionally, the `Squiz.Functions.MultiLineFunctionDeclaration.SpaceAfterUse` error code is excluded as it overlaps with the `Generic.WhiteSpace.LanguageConstructSpacing` sniff, which also checks this. Notes about changes in behaviour before/after this change: * If the open & close parentheses are not on the same line, the space on the inside of the parentheses is no longer checked (as it is seen as a multi-line function declaration for which different rules may apply). * While not commonly used in WP, for multi-line function declarations, the sniff will now enforce one parameter per line with the first parameter on the line _after_ the open parenthesis and the close parenthesis on the line after the last parameter and indented the same as the start of the function declaration statement. A function is considered multi-line when the open and close parentheses are not on the same line, which means that for closures with `use` statements, these rules will apply to both the function parameter list as well as the use parameter list. * It is no longer possible to choose the spacing between the `function` keyword for closures and the open parenthesis. This will no always be enforced to be a single space, which is in line with PSR12. A check of WP Core showed that there was no consistency at all regarding this spacing, with approximately 50/50 of closures having no space vs 1 space, so defering to PSR12 and enforcing consistency in this, seems like a reasonable choice. Other notes: * The `WordPress.WhiteSpace.ControlStructureSpacing` sniff did not support formatting checks for PHP 7.4 arrow functions. At this time, the `Squiz.Functions.MultiLineFunctionDeclaration` sniff does not do so either. There is a PR open upstream squizlabs/php_codesniffer 3661 to add support for arrow functions, though that PR still needs an update for the (very inconsistent) rule chosen by PSR-PER to [enforce _no_ space between the `fn` keyword and the open parenthesis for arrow functions](php-fig/per-coding-style#53). * There is also a PR open upstream - squizlabs/php_codesniffer 3739 - to fix two fixer issues. At this time, these do not pose a problem for WP Core as (aside from the closure keyword spacing), WP Core is "clean", but would be nice if that PR got merged to prevent future issues. * While doing the research for this PR, I discovered an issue with the `Generic.Functions.OpeningFunctionBraceKernighanRitchie` sniff. It doesn't check the spacing before the open brace for empty functions. PR squizlabs/php_codesniffer 3869 has been opened to fix that. As empty functions are the exception, not the rule, I'm hoping it will get merged before any issues about this are reported. Fixes 1101 Note: check 8 identified in issue 1101 is still open, but there is a separate issue open to discuss that in more depth - 1474 - and that issue remains open (for now).
Now the function began to look like everything was thrown into one pile... fn(string $foo) => $foo;
fn(string $bar) => $bar; It's ugly and inconvenient. Also difficult to read. The option with a space looks much better and more elegant: fn (string $foo) => $foo;
fn (string $bar) => $bar; But, since we removed the spaces from the arrow functions, why not remove the spaces in other places as well? (string)$foo
(int)$bar
function(string $foo) {} |
Per the accepted Arrow Functions RFC and per its author, short closures were intended to be written without a space after the
fn
keyword. This is also the default formatting enforced by PhpStorm.PHP-CS-Fixer was an outlier which incorrectly enforced spacing after the
fn
keyword using the same setting as for thefunction
keyword. This was a bug and has been corrected with the addition of a separateclosure_fn_spacing
setting (though this setting still defaults toone
for backwards compatibility - the plan was to change it to enforce no space in the next major 4.0 version). But the current PER coding style spec may get in the way of this plan.Since the primary goal of arrow functions is to avoid the verbosity of anonymous functions, requiring a space after the
fn
keyword is a step backwards, and also doesn't align with general usage promoted by PhpStorm as well as the accepted PHP RFC and documentation.The section on Short Closures was not added until the 17th of July by #17, which was after the 1.0.0 spec was approved/released on June 9, so I'm hoping it's not too late to correct it.