This was floated in 2003 but had weak advocation and didn't seem to come to a decisive resolution:

        http://marc.info/?l=php-internals&m=106685833011253&w=2

Basically, the proposal is to modify the grammar to allow trailing commas in function and method calls, so this becomes a parseable PHP construct:

        f(1, 2, 3,);

This patch applies only to function and method calls; it does not apply to function or method definitions. It also does not allow the degenerative case of "f(,)".

The real value of relaxing this rule is in nontrivial cases that span across multiple lines:
        
        sprintf(
                'long example pattern with %d conversions: %s',
                $several,
                $conversions
        );

This sort of construction makes the code more readable but also exposes you to trailing-comma errors. You can easily introduce an error either by removing the last parameter or by changing parameter order. At least in my experience, these are relatively common syntax errors, and ones that are easy to make when making edits that are apparently minor. In the above example, I can remove the "%s" conversion, remove the "$conversions" parameter, and inadvertently introduce a syntax error because I have neglected to remove the comma after "$several". Similarly, I can change the parameter order by modifying the string and swapping $several for $conversions, but introduce a syntax error by neglecting to move the comma.

In the current grammar, if a function or method call has been written with parameters broken across multiple lines, adding or removing a trailing parameter means you need to modify two lines of code instead of one. This muddies and reduces the value of "blame" features in revision control. It also makes diffs slightly larger and noisier, which can make code reviews take a little longer since you have to scan the line and make sure the only change is to the trailing comma.

The looser grammar is easier to use and more consistent: it's easier to add, remove, or move parameters in an editor since you only need to use line-oriented editor operations, and you don't need to mentally distinguish between an array context and a parameter context.

In the original thread, Andi Gutmans explained that the decision to allowing trailing commas in array() literals is supported by the argument that it makes code generation easier. It seems like this argument applies to trailing commas in function definitions just as easily, and that the general ease-of-use arguments laid out above provide at least as much value as this (particularly since this specific code generation problem is solvable with implode()).

Andi also argued that this reduces readability and prevents assigning semantics to a trailing comma in the future. While I agree that it reduces readability in the "f(1, 2,)" case, I disagree that it reduces readability in the less trivial multi-line case and it greatly enhances "writeability". The possibility that the language would ever benefit from assigning semantics here, while worth considering, seems small. While my language architect credentials are pretty weak, I can't think of any reasonable meaning. Many languages accept trailing commas in data definitions (apparently including Java (!) now[1]), and some (such as Python[2]) accept them in calls; in all cases, the behavior is to ignore them. If PHP provided a different semantic, this would be somewhat startling.

In general, trailing commas are increasingly an accepted part of the grammars of modern languages. Beyond Java, Ruby and Python, Firefox now accepts them in Javascript object definitions (which is surefire way to tell that someone didn't test in IE). While they are more often accepted in data definitions than calls, I don't see a strong reason to distinguish between the cases.

This change has no impact on backward compatibility. It does makes it slightly more difficult to write code which runs across multiple versions of PHP. However, because it fails fast and explicitly, it's an error which is easy to detect and resolve when you decide you want to support more versions of PHP with your project. It's also straightforward to write a script that uses the tokenizer to safely and unambiguously remove trailing commas (I'd be happy to furnish such a script if people think there's value in it and there's a reasonable place to put it).

The diff in the original thread still seems correct, at least against a relatively recent release -- I applied it to PHP 5.2.5 and ran the tests, as well as verifying that the build could parse and execute code which used trailing commas in calls.

So, what's the feeling on this? We're trying to weigh the merits of rolling it into our stack at Facebook, but we'd feel a lot more comfortable if it was present upstream.

Thanks,
Evan Priestley

[1] http://java.sun.com/docs/books/jls/second_edition/html/ arrays.doc.html#11358
[2] http://docs.python.org/ref/calls.html

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to