# RFC: Trailing commas in list syntax

- Status: Implemented (PHP 7.2)
- Authors: Sammy Kaye Powers, me@sammyk.me
- Date: 2015-11-03 (discussion); 2017-01-27 (voting)
- Version: 0.1
- Original: https://wiki.php.net/rfc/list-syntax-trailing-commas
- Page: https://externals.io/rfc/list-syntax-trailing-commas
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

## Votes

### Allow trailing commas in function/method arguments (declarations and calls) (closed)

Yes: 24 · No: 20

Voters: adambaratz (No), ashnazg (Yes), bishop (Yes), bwoebi (No), cmb (No), danack (Yes), daverandom (Yes), derick (No), dmitry (No), eliw (No), galvao (Yes), jhdxr (No), joey (Yes), kalle (No), kelunik (Yes), keyur (Yes), kguest (Yes), laruence (No), lcobucci (No), leigh (No), malukenho (No), marcio (Yes), mariano (Yes), mbeccati (No), mfonda (Yes), mike (Yes), nikic (Yes), ocramius (Yes), pajoye (Yes), pierrick (No), pmjones (No), pollita (Yes), rmf (Yes), salathe (No), sammyk (Yes), sebastian (No), stas (No), svpernova09 (Yes), thekid (Yes), trowski (Yes), weierophinney (Yes), yunosh (Yes), zeev (No), zimt (No)

### Allow trailing commas in grouped namepaces (closed)

Yes: 30 · No: 9

Voters: adambaratz (Yes), ajf (Yes), ashnazg (Yes), bishop (Yes), bwoebi (No), colinodell (Yes), daverandom (Yes), dmitry (No), eliw (No), galvao (Yes), joey (Yes), kalle (No), kelunik (Yes), keyur (Yes), kguest (Yes), lcobucci (Yes), leigh (Yes), levim (Yes), malukenho (Yes), marcio (Yes), mariano (Yes), mbeccati (Yes), mike (Yes), nikic (Yes), ocramius (Yes), pajoye (Yes), pierrick (No), pollita (Yes), rmf (Yes), salathe (No), sammyk (Yes), sebastian (No), stas (No), thekid (Yes), trowski (Yes), weierophinney (Yes), yunosh (Yes), zeev (Yes), zimt (No)

### Allow trailing commas in interface implementations on a class (closed)

Yes: 8 · No: 29

Voters: adambaratz (No), ajf (No), ashnazg (No), bishop (Yes), bwoebi (No), cmb (No), daverandom (No), eliw (No), galvao (No), jhdxr (No), joey (Yes), kalle (No), kelunik (No), keyur (No), kguest (No), lcobucci (No), leigh (No), levim (No), malukenho (No), marcio (Yes), mariano (No), mbeccati (No), mfonda (No), mike (Yes), nikic (No), ocramius (No), pajoye (No), pierrick (No), pollita (Yes), salathe (No), sammyk (Yes), sebastian (No), stas (No), trowski (No), weierophinney (Yes), yunosh (Yes), zeev (No)

### Allow trailing commas in trait implementations on a class (closed)

Yes: 7 · No: 29

Voters: adambaratz (No), ajf (No), ashnazg (No), bishop (Yes), bwoebi (No), cmb (No), daverandom (No), eliw (No), galvao (No), jhdxr (No), joey (Yes), kalle (No), kelunik (No), keyur (No), kguest (No), lcobucci (No), leigh (No), levim (No), malukenho (No), marcio (Yes), mariano (No), mbeccati (No), mike (Yes), nikic (No), ocramius (No), pajoye (No), pierrick (No), pollita (No), salathe (No), sammyk (Yes), sebastian (No), stas (No), trowski (No), weierophinney (Yes), yunosh (Yes), zeev (No)

### Allow trailing commas in class member lists (closed)

Yes: 7 · No: 29

Voters: adambaratz (No), ajf (No), ashnazg (No), bishop (Yes), bwoebi (No), cmb (No), daverandom (No), eliw (No), galvao (No), jhdxr (No), joey (Yes), kalle (No), kelunik (No), keyur (No), kguest (No), lcobucci (No), leigh (No), levim (No), malukenho (No), marcio (Yes), mariano (No), mbeccati (No), mike (Yes), nikic (No), ocramius (No), pajoye (No), pierrick (No), pollita (No), salathe (No), sammyk (Yes), sebastian (No), stas (No), trowski (No), weierophinney (Yes), yunosh (Yes), zeev (No)

### Allow trailing commas in use lists for anonymous functions (closed)

Yes: 16 · No: 22

Voters: adambaratz (No), ashnazg (Yes), bishop (Yes), bwoebi (No), cmb (No), daverandom (Yes), derick (No), dmitry (No), eliw (No), galvao (No), jhdxr (No), joey (Yes), kalle (No), kelunik (Yes), keyur (No), kguest (Yes), lcobucci (No), leigh (No), levim (No), malukenho (No), marcio (Yes), mariano (Yes), mbeccati (No), mike (Yes), nikic (Yes), ocramius (Yes), pajoye (No), pierrick (No), pmjones (No), pollita (Yes), salathe (No), sammyk (Yes), sebastian (No), stas (No), trowski (Yes), weierophinney (Yes), yunosh (Yes), zeev (No)

## Discussions on the mailing list

- [\[RFC\]\[DISCUSSION\] Trailing commas in all list syntax](https://externals.io/message/89057.md) — started on 2015-11-03, 6 messages
- [Permitting trailing commas in closure use() declarations](https://externals.io/message/110715.md) — started on 2020-06-24, 3 messages
- [\[RFC\] Allow trailing comma in closure use list](https://externals.io/message/110804.md) — started on 2020-07-01, 1 messages

---

## 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 [original RFC to allow trailing commas in function arguments](https://externals.io/rfc/revisit-trailing-comma-function-args) to all list syntax.

Arrays in PHP have long since supported trailing commas.

#### Trailing array commas

```php
$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

```php
<?php
use Foo\Bar\{
    Foo,
    Bar,
    Baz,
};
```

## Proposal

This RFC proposes allowing trailing commas in all list syntax in order to:

1. Offer a consistent API and match the existing array functionality.
2. Make it easy to append new elements to a list in user-land.
3. Have cleaner diffs (so only one line shows up as being modified when appending elements instead of two).
4. It makes code reviews a tiny bit faster and for really large codebases, that time adds up. ([Sara Golemon](https://people.php.net/user.php?username=pollita) explained [why HHVM added the trailing comma syntax](https://www.mail-archive.com/internals@lists.php.net/msg81138.html).)

The following lists would allow trailing commas:

1. Grouped namepaces
2. Function/method arguments (declarations &amp; calls)
3. Interface implementations on a class
4. Trait implementations on a class
5. Class member lists
6. Inheriting variables from the parent scope in anonymous functions

[Marcio Almada](https://people.php.net/user.php?username=marcio) posted a gist with [examples of trailing commas](https://gist.github.com/marcioAlmada/75f8f1d47da5dcac2e57) for the various lists (shown below):

#### Trailing commas for all lists

```php
<?php
// Grouped namepaces
use Foo\Bar\{ Foo, Bar, Baz, };
 
// Arrays (already possible)
$array = [1, 2, 3,];
 
// Function/method arguments (call)
fooCall($arg1, $arg2, $arg3,);
 
class Foo implements
    // Interface implementations on a class
    FooInterface,
    BarInterface,
    BazInterface,
{
    // Trait implementations on a class
    use
        FooTrait,
        BarTrait,
        BazTrait,
    ;
 
    // Class member lists
    const
        A = 1010,
        B = 1021,
        C = 1032,
        D = 1043,
    ;
    protected
        $a = 'foo',
        $b = 'bar',
        $c = 'baz',
    ;
    private
        $blah,
    ;
 
    // Function/method arguments (declaration)
    function something(FooBarBazInterface $in, FooBarBazInterface $out,) : bool
    {
    }
}
 
// Inheriting variables from the parent scope in anonymous functions
$foo = function ($bar) use (
    $a,
    $b,
    $c,
) {
	// . . . 
};
```

## 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.

```php
foo(
    ...$args,
    ...$moreArgs,
    ...$evenMoreArgs,
);
```

### Why allocate resources to make this happen

The actual implementation for adding tailing commas to function arguments/calls is [two lines](https://github.com/sgolemon/php-src/compare/master...trailing-comma#diff-7eff82c2c5b45db512a9dc49fb990bb8L517). Implementing the functionality to all lists would not require many more changes to the php-src codebase.

### You could just use leading commas

```php
function foo(
   $bar
  ,$baz
  ,$boo
) { ... }
```

1. Leading commas would break away from PSRs
2. Parsing leading commas cause cognitive overhead whereas standard practice calls for trailing commas

### The arguments for &amp; 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 &amp; calls)

```php
// Function/method arguments (call)
fooCall(
    $arg1,
    $arg2,
    $arg3,
);
 
// Function/method arguments (declaration)
function something(
    FooBarBazInterface $in,
    FooBarBazInterface $out,
) : bool {
}
```

**Vote: Allow trailing commas in function/method arguments (declarations and calls)** — Yes: 24 · No: 20 (closed)

### Grouped namepaces

```php
<?php
use Foo\Bar\{
    Foo,
    Bar,
    Baz,
};
```

**Vote: Allow trailing commas in grouped namepaces** — Yes: 30 · No: 9 (closed)

### Interface implementations on a class

```php
class Foo implements
    FooInterface,
    BarInterface,
    BazInterface,
{
}
```

**Vote: Allow trailing commas in interface implementations on a class** — Yes: 8 · No: 29 (closed)

### Trait implementations on a class

```php
class Foo
{
    use
        FooTrait,
        BarTrait,
        BazTrait,
    ;
}
```

**Vote: Allow trailing commas in trait implementations on a class** — Yes: 7 · No: 29 (closed)

### Class member lists

```php
class Foo
{
    const
        A = 1010,
        B = 1021,
        C = 1032,
        D = 1043,
    ;
    protected
        $a = 'foo',
        $b = 'bar',
        $c = 'baz',
    ;
    private
        $blah,
    ;
}
```

**Vote: Allow trailing commas in class member lists** — Yes: 7 · No: 29 (closed)

### Inheriting variables from the parent scope in anonymous functions

```php
$foo = function ($bar) use (
    $a,
    $b,
    $c,
) {
	// . . . 
};
```

**Vote: Allow trailing commas in use lists for anonymous functions** — Yes: 16 · No: 22 (closed)

## Patches and Tests

The [original patch by Sara Golemon](https://github.com/sgolemon/php-src/compare/master...trailing-comma).
