rfc:additional-splat-usage

This is an old revision of the document!


PHP RFC: Additional Usage for the Splat Operator

Introduction

This RFC proposes an additional usage in array literal declarations for the argument unpacking operator introduced in PHP 5.6.

Proposal

The argument unpacking operator ...$var (hereafter referred to as the “splat” operator) currently permits unpacking arrays into an argument list when variadic functions are called, as well as collecting variadic arguments into an array in the callee. However, there are other cases where it can make sense to use a similar construct for brevity and readability. This RFC covers one of these cases which is commonly available in other languages that support a similar operator.

Combining arrays in literal declaration syntax

A common operation is to merge an existing array stored in a variable with another array that is being declared literally. Currently this is usually done using array_merge() or the + operator:

$arr1 = ['d' => 4, 'e' => 5, 'f' => 6];
$arr2 = array_merge(['a' => 1, 'b' => 2, 'c' => 3], $arr1);
$arr3 = ['a' => 1, 'b' => 2, 'c' => 3] + $arr1;

array_merge() is quite verbose and carries the overheads of invoking a function. The + operator is not always suitable for such an operation and has a cognitive overhead when reading the code, because of the differences in behaviour from array_merge().

This RFC proposes allowing the splat operator to be used in array literals as another way to perform this operation:

$arr1 = ['d' => 4, 'e' => 5, 'f' => 6];
$arr2 = ['a' => 1, 'b' => 2, 'c' => 3, ...$arr1];

The new syntax gives equivalent behaviour to the array_merge() example above, where the contents of $arr1 are appended to the array literal, and stored in $arr2. The same rules for merging are followed; in the case of duplicated string keys, the later value overwrites the earlier when read from left to right, and numerically indexed arrays are appropriately re-keyed and appended. Any number of variables can be unpacked at any position in the array literal, and may be combined with regular element declarations in any order.

Backward Incompatible Changes

None.

Proposed PHP Version(s)

This RFC targets PHP 7.

RFC Impact

To SAPIs

None.

To Existing Extensions

None.

To Opcache

TODO.

Open Issues

  • What impact, if any, will this have on Opcache?

Unaffected PHP Functionality

No existing functionality is affected by this, other than the new capabilities outlined in the main proposal.

Future Scope

Another feature common in languages that implement a similar construct is the ability to store “the rest” of the elements in a list() assignment operation, in such a manner that the following operations would be equivalent:

$arr = [1, 2, 3, 4, 5, 6];
 
// how we can currently do this
$theRest = array_splice($arr, 2);
list($one, $two) = $arr;
 
// something that could be implemented instead
list($one, $two, ...$theRest) = $arr;

This case is not covered by this RFC, because the nature of PHP arrays combined with the way the list operator works makes this ambiguous with respect to how it should function in the case of arrays which are not simply contiguously 0-indexed. A future RFC could look to implement this, if an agreement could be reached on how it should function.

Proposed Voting Choices

Simple yes/no. As this is a language change, the vote would require a 2/3 majority in favour to pass.

Patches and Tests

Nikita Popov has offered to provide an implementation for this feature, should this RFC be accepted.

References

rfc/additional-splat-usage.1415054932.txt.gz · Last modified: 2017/09/22 13:28 (external edit)