rfc:list_keys

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
rfc:list_keys [2016/01/17 17:19] – Fixed named parameters RFC link ajfrfc:list_keys [2017/09/22 13:28] (current) – external edit 127.0.0.1
Line 1: Line 1:
 ====== PHP RFC: Allow specifying keys in list() ====== ====== PHP RFC: Allow specifying keys in list() ======
-  * Version: 1.0+  * Version: 1.1.1
   * Date: 2016-01-17   * Date: 2016-01-17
   * Author: Andrea Faulds, ajf@ajf.me   * Author: Andrea Faulds, ajf@ajf.me
-  * Status: Under discussion+  * Status: Implemented (PHP 7.1)
   * First Published at: http://wiki.php.net/rfc/list_keys   * First Published at: http://wiki.php.net/rfc/list_keys
  
Line 75: Line 75:
 </code> </code>
  
-Keys can not only be literals like <php>2</php> or <php>"foo"</php>, but also constants:+Keys can not only be literals like <php>2</php> or <php>"foo"</php>, but also any expression , including constants or variables (this was not the case in an earlier revision of the RFC, see //Resolved issues//).
  
 <code php> <code php>
Line 84: Line 84:
 ) = $curlOptions; ) = $curlOptions;
 </code> </code>
- 
-However, keys cannot be variables or other expressions: 
  
 <code php> <code php>
-// Parse error: syntax error, ... +list($foo => $bar) = $bar;
-list($foo => $bar) = $array;+
 </code> </code>
- 
-The problem here is that there are two different behaviours that you might expect here: 
- 
-  - <php>$foo</php> is set to the key of the first element in <php>$array</php>, and <php>$bar</php> is set to its key <php>$array</php> (i.e. <php>$bar = reset($array); $foo = key($array);</php>) 
-  - <php>$bar</php> is set to the value of the element in <php>$array</php> with the key <php>$foo</php> (i.e. <php>$bar = $array[$foo];</php>) 
- 
-So, this is not allowed in order to prevent misunderstanding. (However, this might change: see //Open Issues// below.) 
  
 <php>list()</php> elements with and without keys cannot be mixed, unlike in the <php>array()</php> syntax: <php>list()</php> elements with and without keys cannot be mixed, unlike in the <php>array()</php> syntax:
Line 159: Line 149:
  
 Handling of implicit conversions of keys, and of accessing undefined keys, follows the same rules as for regular array indexing. Handling of implicit conversions of keys, and of accessing undefined keys, follows the same rules as for regular array indexing.
 +
 +==== Further Examples ====
 +
 +The use of explicit integer keys can be clearer than regular un-keyed <php>list()</php> in the same situations. Compare these two code snippets performing routing:
 +
 +<code php>
 +$result = $dispatcher->dispatch($httpMethod, $uri);
 +switch ($result[0]) {
 +    case \FastRoute\Dispatcher::FOUND:
 +        list(, $handler, $parts) = $result;
 +        
 +        // ...
 +}
 +</code>
 +
 +<code php>
 +$result = $dispatcher->dispatch($httpMethod, $uri);
 +switch ($result[0]) {
 +    case \FastRoute\Dispatcher::FOUND:
 +        list(1 => $handler, 2 => $parts) = $result;
 +        
 +        // ...
 +}
 +</code>
 +
 +The comma in the version using implicit keys could be missed when reading the code, and here we are mixing two different kinds of indexing: explicit (<php>$result[0]</php>) and positional (<php>list(, $handler, $parts)</php>. In the version using explicit keys, it is harder to miss that the second and third element of the array are being used, and all three keys are expressed in the same, explicit fashion.
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
Line 190: Line 206:
  
 No impact on php.ini. No impact on php.ini.
 +
 +===== Resolved Issues =====
 +
 +==== Should arbitrary expressions be allowed as keys? ====
 +
 +Given this syntax, it was thought there might be potential confusion as to what <php>$foo</php> does:
 +
 +<code php>
 +list($foo => $bar) = $array;
 +</code>
 +
 +The problem was that there were two different behaviours that might be expected here:
 +
 +  - <php>$foo</php> is set to the key of the first element in <php>$array</php>, and <php>$bar</php> is set to its key <php>$array</php> (i.e. <php>$bar = reset($array); $foo = key($array);</php>)
 +  - <php>$bar</php> is set to the value of the element in <php>$array</php> with the key <php>$foo</php> (i.e. <php>$bar = $array[$foo];</php>)
 +
 +So, this was initially not allowed in order to prevent misunderstanding. However, after discussions and further thought, it seemed as though misinterpreting it as doing the first thing (taking the key of the first element) was unlikely, and so we do not need to restrict arbitrary expressions. It also is more useful to accept them, since this means things like object keys (e.g. with SplObjectStorage) can work.
  
 ===== Open Issues ===== ===== Open Issues =====
  
-Due to the aforementioned potential confusion, arbitrary expressions (including variables) are not accepted as keys, merely constants. However, if we think that the two possibilities are unlikely to be confused, we could allow variable keys. This would be mostly useful for ''ArrayAccess''-implementing objects, which can use objects as keys. Allowing arbitrary expressions here would be trivial to implement.+None.
  
 ===== Unaffected PHP Functionality ===== ===== Unaffected PHP Functionality =====
Line 200: Line 233:
  
 ===== Future Scope ===== ===== Future Scope =====
 +
 +__The following is merely **potential future scope** and **is not part of the proposal proper, nor being voted on in this RFC**.__
  
 It would be useful to support <php>list()</php> in function parameter lists, so that an "argument bag" parameter could be immediately destructured:  It would be useful to support <php>list()</php> in function parameter lists, so that an "argument bag" parameter could be immediately destructured: 
Line 221: Line 256:
 </code> </code>
  
-This would be more practical to implement than the [[rfc:named_params|Named Parameters]] RFC, and could be applied to existing function which already use the "argument bag" pattern. Destructuring syntax in parameter declarations is a feature in some other programming languages, for example [[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Pulling_fields_from_objects_passed_as_function_parameter|in ECMAScript 6]]. Destructuring of arrays is also a subset of what is possible with pattern matching, which is a feature of many functional programming languages.+This would be more practical to implement than the [[rfc:named_params|Named Parameters]] RFC, and could be applied to existing functions which already use the "argument bag" pattern. Destructuring syntax in parameter declarations is a feature in some other programming languages, for example [[https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Pulling_fields_from_objects_passed_as_function_parameter|in ECMAScript 6]]. Destructuring of arrays is also a subset of what is possible with pattern matching, which is a feature of many functional programming languages.
  
 If we implemented this, we might want to extend the syntax to support type declarations: If we implemented this, we might want to extend the syntax to support type declarations:
Line 245: Line 280:
 It has been suggested that at some point <php>list()</php> may be given an alternate syntax of <php>[]</php>, just as happened for <php>array()</php>. This would mean that there would be symmetry between the syntax for creating an array (<php>[1, 2, 3]</php>) and destructuring it (<php>[$a, $b, $c]</php>), as there is in some other programming languages. This proposal to allow specifying keys would not present any issues for this alternate syntax that I am aware of. It has been suggested that at some point <php>list()</php> may be given an alternate syntax of <php>[]</php>, just as happened for <php>array()</php>. This would mean that there would be symmetry between the syntax for creating an array (<php>[1, 2, 3]</php>) and destructuring it (<php>[$a, $b, $c]</php>), as there is in some other programming languages. This proposal to allow specifying keys would not present any issues for this alternate syntax that I am aware of.
  
-===== Proposed Voting Choices ===== +===== Vote ===== 
-The vote will be a simple Yes/No vote on whether to accept the RFC and merge the patch into PHP master.+The vote is a simple Yes/No vote on whether to accept the RFC and merge the patch into PHP master. As this adds a feature to the language, this RFC requires a 2/3 majority to succeed.
  
-As this adds a feature to the language, this RFC requires a 2/3 majority to succeed.+Voting started on 2016-02-05 and ended on 2016-02-14. 
 + 
 +<doodle title="Accept the Allow specifying keys in list() RFC for PHP 7.1, and merge the patch into master?" auth="ajf" voteType="single" closed="true"> 
 +   * Yes 
 +   * No 
 +</doodle>
  
 ===== Patches and Tests ===== ===== Patches and Tests =====
  
-I have written a complete patch with tests, and made a pull request: https://github.com/php/php-src/pull/1730+php-src has a complete pull request including tests: https://github.com/php/php-src/pull/1730
  
-There is not yet patch for the language specification.+There is a language specification pull request, also with tests: https://github.com/php/php-langspec/pull/152
  
 ===== Implementation ===== ===== Implementation =====
 +
 +Merged into php-src for PHP 7.1: https://github.com/php/php-src/commit/37c8bb58686b2d86f145ebe4fe39854f5951dcd7
 +
 +Merged into php-langspec for PHP 7.1: https://github.com/php/php-langspec/commit/0b1a497a6c847f6566f32057f55259f68bb9ce38
 +
 After the project is implemented, this section should contain  After the project is implemented, this section should contain 
-  - the version(s) it was merged to 
-  - a link to the git commit(s) 
   - a link to the PHP manual entry for the feature   - a link to the PHP manual entry for the feature
  
 ===== References ===== ===== References =====
  
-  * [[rfc:named_parameters|Named Parameters RFC]]+  * [[rfc:named_params|Named Parameters RFC]]
  
 ===== Rejected Features ===== ===== Rejected Features =====
Line 272: Line 315:
 ===== Changelog ===== ===== Changelog =====
  
 +  * v1.1.1 (2016-02-12) - Added further example
 +  * v1.1 - Resolved issue of whether to permit arbitrary expressions in keys (yes)
   * v1.0 - First announced version   * v1.0 - First announced version
rfc/list_keys.1453051150.txt.gz · Last modified: 2017/09/22 13:28 (external edit)