Both sides previous revisionPrevious revisionNext revision | Previous revision |
rfc:variadics [2013/08/28 20:37] – nikic | rfc:variadics [2017/09/22 13:28] (current) – external edit 127.0.0.1 |
---|
* Date: 2013-08-27 | * Date: 2013-08-27 |
* Author: Nikita Popov <nikic@php.net> | * Author: Nikita Popov <nikic@php.net> |
* Status: Under Discussion | * Status: Implemented in PHP 5.6 ([[https://github.com/php/php-src/commit/0d7a6388663b76ebed6585ac92dfca5ef65fa7af|git:0d7a6388]]) |
* Proposed for: PHP 5.6 | |
* Patch: https://github.com/php/php-src/pull/421 | * Patch: https://github.com/php/php-src/pull/421 |
* Mailing list discussion: http://markmail.org/message/uhewgv7zaagkgzdv | * Mailing list discussion: http://markmail.org/message/uhewgv7zaagkgzdv |
| |
The ''%%...$params%%'' syntax indicates that this is a variadic function and that all arguments after ''$query'' should be put into the ''$params'' array. Using the new syntax both of the issues mentioned above are solved. | The ''%%...$params%%'' syntax indicates that this is a variadic function and that all arguments after ''$query'' should be put into the ''$params'' array. Using the new syntax both of the issues mentioned above are solved. |
| |
| ==== Population of variadic parameter ==== |
| |
| The following example shows how the variadic parameter ''%%...$params%%'' is populated depending on the number of passed arguments: |
| |
| <code php> |
| function fn($reqParam, $optParam = null, ...$params) { |
| var_dump($reqParam, $optParam, $params); |
| } |
| |
| fn(1); // 1, null, [] |
| fn(1, 2); // 1, 2, [] |
| fn(1, 2, 3); // 1, 2, [3] |
| fn(1, 2, 3, 4); // 1, 2, [3, 4] |
| fn(1, 2, 3, 4, 5); // 1, 2, [3, 4, 5] |
| </code> |
| |
| ''$params'' will be an empty array if the number of passed arguments is smaller than the number of declared parameters. Any further arguments will be added to the ''$params'' array (in the order in which they were passed). The ''$params'' array is using continuous zero-based indices. |
| |
==== By-reference capture ==== | ==== By-reference capture ==== |
==== Userland ==== | ==== Userland ==== |
| |
This change does not break backwards comparability for userland code. | This change does not break backwards compatibility for userland code. |
| |
In particular, this RFC does not propose to deprecate or remove the ''func_get_args()'' family of functions, at least not any time soon. | In particular, this RFC does not propose to deprecate or remove the ''func_get_args()'' family of functions, at least not any time soon. |
| |
* ''%%$args...%%''. With ref-modifier (''%%&$args...%%'') this does not show well that the individual arguments are references, rather than ''$args'' itself. With typehint (''%%array $args...%%'') it also looks like the typehint applies to ''$args'' itself rather than all variadic arguments. | * ''%%$args...%%''. With ref-modifier (''%%&$args...%%'') this does not show well that the individual arguments are references, rather than ''$args'' itself. With typehint (''%%array $args...%%'') it also looks like the typehint applies to ''$args'' itself rather than all variadic arguments. |
* ''*$args''. This is the syntax that both Ruby and Python use. For PHP this does not work well because ''*$'' is a weird combination. It gets worse with a by-reference capture: ''&*$args''. This looks like a random sequences of special characters. | * ''*$args''. This is the syntax that both Ruby and Python use. For PHP this does not work well because ''*$'' is a weird combination. It gets worse with a by-reference capture: ''&*$args''. This looks like a random sequences of special characters. Combined with a typehint the syntax looks a lot like a pointer: ''Foo *$args''. |
* ''params $args''. This is what C# does. This would require making ''params'' a keyword. Furthermore this doesn't have any nice way to declare typehints. In C# this is done using ''params type[] args'', but PHP doesn't have ''type[]'' hints and introducing them only here doesn't seem right. | * ''params $args''. This is what C# does. This would require making ''params'' a keyword. Furthermore this doesn't have any nice way to declare typehints. In C# this is done using ''params type[] args'', but PHP doesn't have ''type[]'' hints and introducing them only here doesn't seem right. |
| |
The proposed syntax is also used by Java and will be used in [[http://wiki.ecmascript.org/doku.php?id=harmony:rest_parameters|Javascript (ECMAScript Harmony proposal)]]. | The proposed syntax is also used by Java and will be used in [[http://wiki.ecmascript.org/doku.php?id=harmony:rest_parameters|Javascript (ECMAScript Harmony proposal)]]. Go and C++ also employ a similar syntax. |
| |
===== Patch ===== | ===== Patch ===== |
| |
Patch available in PR#421: https://github.com/php/php-src/pull/421 | Patch available in PR#421: https://github.com/php/php-src/pull/421 |
| |
| ===== Vote ===== |
| |
| The vote started on 16.09.2013 and ended on 23.09.2013. There were 36 votes in favor and one against, as such the necessary two-third majority is met and this feature is **accepted**. |
| |
| <doodle title="Should the proposed variadic-function syntax be added in PHP 5.6 (master)?" auth="nikic" voteType="single" closed="true"> |
| * Yes |
| * No |
| </doodle> |
| |
===== Argument unpacking ===== | ===== Argument unpacking ===== |
| |
A related syntactical element is the "splat" or "scatter" operator: | The [[rfc:argument_unpacking|argument unpacking RFC]] introduces the following related syntax: |
| |
<code php> | <code php> |
$db->query($query, ...$params); | $db->query($query, ...$params); |
</code> | </code> |
| |
This operator would unpack an array into an argument list (similarly to ''call_user_func_array''). It is not part of this RFC, but I plan to implement this in a separate proposal. | |