====== 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]].