====== PHP RFC: Trailing Commas In List Syntax ======
* Version: 0.1
* Date: 2015-11-03 (discussion); 2017-01-27 (voting)
* Author: Sammy Kaye Powers, me@sammyk.me
* Status: Implemented in PHP 7.2 (Grouped namepaces only)
* First Published at: https://wiki.php.net/rfc/revisit-trailing-comma-function-args, https://wiki.php.net/rfc/trailing-comma-function-args
===== Introduction =====
This RFC proposes allowing trailing commas for all list syntax.
Per the feedback on the internals list, this RFC broadens the scope of the [[rfc:revisit-trailing-comma-function-args|original RFC to allow trailing commas in function arguments]] to all list syntax.
Arrays in PHP have long since supported trailing commas.
=== Trailing array commas ===
$foo = [
'foo',
'bar',
];
This makes for clean diffs and easy appending of new values in user-land.
Unfortunately, the other lists do not share the same luxury.
=== Raises a parse error ===
===== Proposal =====
This RFC proposes allowing trailing commas in all list syntax in order to:
- Offer a consistent API and match the existing array functionality.
- Make it easy to append new elements to a list in user-land.
- Have cleaner diffs (so only one line shows up as being modified when appending elements instead of two).
- It makes code reviews a tiny bit faster and for really large codebases, that time adds up. ([[https://people.php.net/user.php?username=pollita|Sara Golemon]] explained [[https://www.mail-archive.com/internals@lists.php.net/msg81138.html|why HHVM added the trailing comma syntax]].)
The following lists would allow trailing commas:
- Grouped namepaces
- Function/method arguments (declarations & calls)
- Interface implementations on a class
- Trait implementations on a class
- Class member lists
- Inheriting variables from the parent scope in anonymous functions
[[https://people.php.net/user.php?username=marcio|Marcio Almada]] posted a gist with [[https://gist.github.com/marcioAlmada/75f8f1d47da5dcac2e57|examples of trailing commas]] for the various lists (shown below):
=== Trailing commas for all lists ===
===== Discussion Points =====
There are a number of questions that have already been discussed on the internals list.
==== How will it work with variadics? ====
PHP allows for multiple splats in one call so trailing commas would work the same way.
foo(
...$args,
...$moreArgs,
...$evenMoreArgs,
);
==== Why allocate resources to make this happen ====
The actual implementation for adding tailing commas to function arguments/calls is [[https://github.com/sgolemon/php-src/compare/master...trailing-comma#diff-7eff82c2c5b45db512a9dc49fb990bb8L517|two lines]]. Implementing the functionality to all lists would not require many more changes to the php-src codebase.
==== You could just use leading commas ====
function foo(
$bar
,$baz
,$boo
) { ... }
- Leading commas would break away from PSRs
- Parsing leading commas cause cognitive overhead whereas standard practice calls for trailing commas
==== The arguments for & against are weak ====
**TL;DR:**
* **For it:** It's handy. (And the reasons detailed above).
* **Against:** It's ugly. There are only minor gains.
===== Backward Incompatible Changes =====
This change would have no breaking changes.
===== Proposed PHP Version =====
PHP 7.2
===== Proposed Voting Choices =====
Each trailing comma list syntax has its own vote and requires a 2/3 majority to pass.
==== Function/method arguments (declarations & calls) ====
// Function/method arguments (call)
fooCall(
$arg1,
$arg2,
$arg3,
);
// Function/method arguments (declaration)
function something(
FooBarBazInterface $in,
FooBarBazInterface $out,
) : bool {
}
* Yes
* No
==== Grouped namepaces ====
* Yes
* No
==== Interface implementations on a class ====
class Foo implements
FooInterface,
BarInterface,
BazInterface,
{
}
* Yes
* No
==== Trait implementations on a class ====
class Foo
{
use
FooTrait,
BarTrait,
BazTrait,
;
}
* Yes
* No
==== Class member lists ====
class Foo
{
const
A = 1010,
B = 1021,
C = 1032,
D = 1043,
;
protected
$a = 'foo',
$b = 'bar',
$c = 'baz',
;
private
$blah,
;
}
* Yes
* No
==== Inheriting variables from the parent scope in anonymous functions ====
$foo = function ($bar) use (
$a,
$b,
$c,
) {
// . . .
};
* Yes
* No
===== Patches and Tests =====
The [[https://github.com/sgolemon/php-src/compare/master...trailing-comma|original patch by Sara Golemon]].