rfc:list_reference_assignment

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_reference_assignment [2014/05/15 19:14] – Withdrew RFC ajfrfc:list_reference_assignment [2017/12/09 12:43] (current) – Implemented nikic
Line 1: Line 1:
- 
 ====== PHP RFC: list() Reference Assignment ====== ====== PHP RFC: list() Reference Assignment ======
-  * Version: 1.0 +  * Version: 2.0 
-  * Date: 2013-10-24 +  * Revived Date: 2016-12-30 
-  * Author: Andrea Faulds, ajf@ajf.me +  * Revived Author: David Walker <dave@mudsite.com> 
-  * Status: Withdrawn+  * Withdrawn: 2014-05-15 
 +  * Original Date: 2013-10-24 
 +  * Original Author: Andrea Faulds, ajf@ajf.me 
 +  * Status: Implemented (in PHP 7.3)
   * First Published at: http://wiki.php.net/rfc/list_reference_assignment   * First Published at: http://wiki.php.net/rfc/list_reference_assignment
  
 ===== Introduction ===== ===== Introduction =====
- +PHP has had list() assignment and reference assignment for a long time. However, it is not currently possible to use reference assignment with list(). This RFC proposes this new syntax to cover this.  The original requests for this feature date back at least 16 years now [1][2].  We will be focusing on the formers syntax proposal for this RFC.
-PHP has had list() assignment and reference assignment for a long time. However, it is not currently possible to use reference assignment with list(). This RFC proposes this new syntax to cover this.+
  
 ===== Proposal ===== ===== Proposal =====
- 
 Under this proposal, a new syntax is introduced: Under this proposal, a new syntax is introduced:
  
Line 25: Line 25:
 $array = [1, 2]; $array = [1, 2];
 $a = $array[0]; $a = $array[0];
-$b = &$array[1];+$b =& $array[1]
 +</code> 
 + 
 +<code php> 
 +/* Note; []= syntax works the same, so the following is functionally equivalent to the example */ 
 +[$a, &$b] = $array;
 </code> </code>
  
Line 33: Line 38:
 $array = [1, 2, 3, [3, 4]]; $array = [1, 2, 3, [3, 4]];
 list(&$a, $b,, list(&$c, $d)) = $array; list(&$a, $b,, list(&$c, $d)) = $array;
 +var_dump($array);
 +/*
 +array(4) {
 +  [0]=>
 +  &int(1)
 +  [1]=>
 +  int(2)
 +  [2]=>
 +  int(3)
 +  [3]=>
 +  array(2) {
 +    [0]=>
 +    &int(3)
 +    [1]=>
 +    int(4)
 +  }
 +}
 +*/
 </code> </code>
  
Line 42: Line 65:
     $a = 7;     $a = 7;
 } }
 +var_dump($array)
 +/*
 +array(2) {
 +  [0]=>
 +  array(2) {
 +    [0]=>
 +    int(7)
 +    [1]=>
 +    int(2)
 +  }
 +  [1]=>
 +  array(2) {
 +    [0]=>
 +    &int(7)
 +    [1]=>
 +    int(4)
 +  }
 +}
 +*/
 </code> </code>
 +(notice here that the reference exists on ''$array[1][0]'' since $a is still in scope after the foreach())
 +
  
-The advantage of adding support for this is that it allows you to use reference assignment for multiple variables at once, which is not currently possible. The syntax here is different from the traditional assignment syntax which places the & before the rvar, not the lvar, but the advantage here is that you can reference assign some, but not all of the variables in list().+The predominant advantage of adding support for this is that it allows you to use reference assignment for multiple variables at once, which is not currently possible. The syntax here is different from the traditional assignment syntax which places the ''&'' before the right-side value, not the left-side value; the advantage here is that you can reference assign some, but not all of the variables in list().
  
-===== Backward Incompatible Changes =====+The RFC also takes into account the possibility of objects being the r-val of the assignment implementing ArrayAccess. 
 +<code php> 
 +class RefArr implements ArrayAccess { 
 +    private $s []; 
 +    function __construct(array $a) { $this->$a; } 
 +    function offsetSet ($k, $v) { $this->s[$k] $v; } 
 +    function &offsetGet ($k) { return $this->s[$k];
 +    function offsetExists ($k) { return isset($this->s[$k]);
 +    function offsetUnset ($k) { unset($this->s[$k]);
 +
 +$a new RefArr(array(1, array(2, 3))); 
 +list(&$one, list($two, &$three)) $a; 
 +$one++; 
 +var_dump($a) 
 +/* 
 +object(RefArr)#1 (1) { 
 +  ["s":"RefArr":private]=
 +  array(2) { 
 +    [0]=
 +    &int(2) 
 +    [1]=
 +    array(2) { 
 +      [0]=
 +      int(2) 
 +      [1]=
 +      &int(3) 
 +    } 
 +  } 
 +
 +*/ 
 +</code>
  
 +===== Backward Incompatible Changes =====
 This introduces no backwards incompatible changes. This introduces no backwards incompatible changes.
  
 ===== Proposed PHP Version(s) ===== ===== Proposed PHP Version(s) =====
 +PHP 7.2
  
-Next PHP 5.x, hopefully 5.6. +===== RFC Impact ===== 
- +==== To Opcache ==== 
-===== Open Issues ===== +Maybe, I don'know enough about opcache to say if changing current ops by adding an extended value would impact.
- +
-My implementation contains a memory leakwhich haven'yet figured out how to fix, when this code is run: +
- +
-<code php> +
-$array = [1, 2]; +
-list(&$a, $b) = $array; +
-list($b, &$a) = $array; +
-</code> +
- +
-Any help fixing that issue is appreciated.+
  
 ===== Proposed Voting Choices ===== ===== Proposed Voting Choices =====
 +Voting starts on 2017-02-06 17:30 UTC and closes on 2017-02-22 20:00 UTC
  
-Merge into PHP 5.6?+2/3 Vote Required 
 +Vote Yes to allow reference assignments as part of list() assignments 
 +Vote No to maintain current functionality
  
-  * Yes +<doodle title="list() Reference Assignments" auth="bp1222" voteType="single" closed="true"> 
-  * No+   * Yes 
 +   * No 
 +</doodle>
  
 ===== Patches and Tests ===== ===== Patches and Tests =====
- +  * Working Implementation: https://github.com/php/php-src/pull/2371 
-https://github.com/TazeTSchnitzel/php-src/compare/ListByReference +  * Language Spec: https://github.com/php/php-langspec/compare/master...bp1222:fix-7930
- +
-Implemented with passing testHowever, as mentioned above in "Open Issues", there is a known memory leakHence, it can't yet be considered a final patch. +
- +
-Any help fixing that issue is appreciated. +
- +
-**EDIT 2014-05-15:** I've withdrawn this RFC, due to discovering that PHP's current approach to parsing and opcode output makes this impossible to implement.+
  
 ===== Implementation ===== ===== Implementation =====
  
-(Not merged into PHP)+Implemented in PHP 7.3 via https://github.com/php/php-src/commit/6d4de4cf0582cf33848826ab78aae58077dc2dea.
  
 ===== References ===== ===== References =====
  
-  * Design taken from a feature request of 13 years ago: https://bugs.php.net/bug.php?id=6768+  * [1] - https://bugs.php.net/bug.php?id=6768 
 +  * [2] - https://bugs.php.net/bug.php?id=7930
  
 ===== Rejected Features ===== ===== Rejected Features =====
  
-None as yet.+===== Change Log ===== 
 +  * v2.0 - Commandeered for revival for PHP 7 implementation. 
 +  * v1.0(and prior) - Initial concept raised for PHP 5.x.  Was withdrawn in 2014. 
 +    * Initial PHP 5 Implementation - https://github.com/TazeTSchnitzel/php-src/compare/ListByReference 
 +    * **EDIT 2014-05-15:** I've withdrawn this RFC, due to discovering that PHP's current approach to parsing and opcode output makes this impossible to implement. 
rfc/list_reference_assignment.1400181247.txt.gz · Last modified: 2017/09/22 13:28 (external edit)