Allowing a trailing comma in function calls will make it more convenient to append arguments in many contexts where it is common to call a function with lots of arguments; especially variadic functions.
A trailing comma has been allowed in array syntax since forever-ever, and in grouped namespace syntax since PHP 7.2.
# Currently possible use Foo\Bar\{ Foo, Bar, }; $foo = [ 'foo', 'bar', ];
Allowing a trailing comma makes sense in these contexts as new values get appended frequently. There is another context wherein appending more values frequently happens: calling a variadic function.
unset( $foo, $bar, $baz, );
A trailing comma in function calls make it crazy convient to invoke any function that takes variable arguments (i.e. using the splat operator ...
or func_get_args()
.)
It is extremely common to send a list of two or more arguments to unset()
to unset variables.
unset( $somethingIDontNeedAnymore, $anotherOneToKill, $letsMakeThisEasy, );
Another extremely common practice is to send a list of variables to a template engine concisely using compact()
.
echo $twig->render( 'index.html', compact( 'title', 'body', 'comments', ) );
Invoking array_merge()
is another great example of how a trailing comma makes values easier to append.
$newArray = array_merge( $arrayOne, $arrayTwo, ['foo', 'bar'], );
When you're quickly debugging with var_dump()
, it's nice to not have to worry about removing that dangling comma in order for your script to run.
var_dump( $whatIsInThere, $probablyABugInThisOne, $oneMoreToCheck, );
Internationalization & localization often makes use of variadic functions such as sprintf()
that usually expand and contract over time.
$en = 'A trailing %s makes %s a happy developer.'; $text = sprintf( $en, 'comma', 'Jane', );
This list of examples is not meant to be exhaustive, but you can see how allowing a trailing comma in function calls fits well within the existing trailing comma contexts (arrays & grouped namespaces).
Method calls also adopt trailing comma functionality.
class Foo { public function __construct(...$args) { // } public function bar(...$args) { // } public function __invoke(...$args) { // } } $foo = new Foo( 'constructor', 'bar', ); $foo->bar( 'method', 'bar', ); $foo( 'invoke', 'bar', );
And closures too.
$bar = function(...$args) { // }; $bar( 'closure', 'bar', );
There are two language constructs that look like functions but aren't that will also allow a trailing comma: unset()
(as mentioned before) and isset()
.
unset($foo, $bar,); var_dump(isset($foo, $bar,));
Yes, there was an RFC to add trailing commas to all list syntax in PHP 7.2. Unfortunately due to an oversight on my end, the vote for function calls and function declarations was combined into one vote so the vote failed (but just barely!)
I was contacted by many “no” voters saying that they would have voted “yes” for function calls, but “no” for function declarations. This RFC proposes allowing a trailing comma in function call syntax only.
We are allowed to put this feature up for vote again since the mandatory 6-month waiting period has passed since the last vote and this RFC targets a new major version of PHP.
None
PHP 7.3
Function declaration syntax will not change. This RFC targets function call syntax only.
# Parse error function bar($a, $b,) { // }
Free-standing commas are not allowed.
# Parse error foo(,);
Multiple trailing commas & leading commas are not allowed.
# Parse error foo('function', 'bar',,); # Also parse error foo(, 'function', 'bar');
Other things that could look like functions like yield
& list()
will go untouched and no other list syntax will be affected.
Requires a 2/3 majority to pass. Voting begins 2017-10-21 18:30 UTC and ends 2017-11-04 18:30 UTC.
This patch, sans the tests, is a trivial three-line change in the parser.
The trailing comma is thrown out at the parser level so there's no runtime computations wasted.
Implemented in PHP 7.3 via https://github.com/php/php-src/commit/b591c329ee3129adbdc35141bb1542d119f7a2a1.