rfc:normalize-array-auto-increment-on-copy-on-write

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:normalize-array-auto-increment-on-copy-on-write [2019/06/19 21:38] wesnetmorfc:normalize-array-auto-increment-on-copy-on-write [2019/06/28 21:13] (current) wesnetmo
Line 1: Line 1:
-====== PHP RFC: Normalize array'"auto-increment" value on copy on write ======+====== PHP RFC: Normalize arrays' "auto-increment" value on copy on write ======
  
   * Version: 0.1   * Version: 0.1
   * Date: 2019-06-19   * Date: 2019-06-19
   * Author: Wes (@WesNetmo)   * Author: Wes (@WesNetmo)
-  * Status: Under Discussion+  * Status: Under discussion
   * First Published at: http://wiki.php.net/rfc/normalize-array-auto-increment-on-copy-on-write   * First Published at: http://wiki.php.net/rfc/normalize-array-auto-increment-on-copy-on-write
  
 ===== Introduction ===== ===== Introduction =====
  
-When an ''array'' is assigned to a new reference, and it is copied, before a modification, due +If two ''array''s are equal/identical, they should remain equal/identical ''array''s after 
-to the copy-on-write behavior, it will result in an array that is identical in any way to the +the same ''array_push(..., $val)'' call is executed on both of them: 
-original one; in factthe copy also covers the "next auto-increment index" value:+ 
 +<PHP> 
 +assert($array1 === $array2); // identical/equal 
 +$array1[] = $array2[] = 123; 
 +assert($array1 === $array2); // still identical/equal 
 +</PHP> 
 + 
 +This is currently not guaranteed, and because of ''array''s' all-doing nature, it is not 
 +possible to always enforce this property -- but it should be in some dangerous cases, 
 +namely when functions from (potential) different authors are interacting. 
 + 
 +----- 
 + 
 +When an ''array'' is assigned to a new reference, and it is copied, before a modification, 
 +due to the copy-on-write behavior, it will result in an ''array'' that is identical in any 
 +way to the original one, inclusive of its "auto-increment" value:
  
 <PHP> <PHP>
Line 19: Line 34:
 $array2 = $array1; $array2 = $array1;
 assert($array2 === [0]); assert($array2 === [0]);
-$array2[] = "push"; // triggers COW+$array2[] = "push"; // triggers COW and then pushes the new entry
  
 print_r($array2); print_r($array2);
Line 29: Line 44:
 </PHP> </PHP>
  
-This behavior happens, unfortunately, also between different scopes. Our code can receive 
-"broken" array-lists from third parties that only appear to be well-indexed array-lists, 
-but that in reality are not, because they were misused during their lifetime (for example, 
-it was used ''unset()'' on them, instead of ''array_pop()''). 
  
-Despite "copy on write", the value-type semantics, and even a different scope, the +This happens also between different function scopes. Our functions can receive "broken" 
-following assertion might fail in some cases:+''array''-lists from third-parties that only appear to be well-indexed, but that in 
 +reality are not, because they were misused during their lifetime (classic example, it was 
 +used ''unset($array[$lastIndex])'' on them, instead of ''array_pop($array)''). 
 + 
 +As result of that, despite "copy on write", the value-type semantics, and even a different 
 +scope, the following assertion can fail in some cases:
  
 <PHP> <PHP>
Line 50: Line 66:
 test($poison); test($poison);
 </PHP> </PHP>
- 
-In other words, if ''$a'' and ''$b'' are equal/identical arrays, they should remain 
-equal/identical arrays, after the same ''array_push(..., $val)'' is executed on both of 
-them. 
  
 ===== Proposal ===== ===== Proposal =====
  
-This RFC proposes to reset the "next auto-increment" value in copies triggered by "copy +This RFC proposes to reset the "auto-increment" value in copies triggered by "copy on 
-on write", in order to guarantee a deterministic behavior to foreign scopes especially. +write", in order to guarantee a deterministic behavior to foreign scopes especially. The 
-The "next auto-increment" value of the new variable reference must be equivalent to the +"auto-increment" value of the new variable reference must be equivalent to the 
-"next auto-increment" value that the array would have if it was re-created entry by entry,+"auto-increment" value that the ''array'' would have if it was re-created entry by entry,
 as follows: as follows:
  
Line 70: Line 82:
 </PHP> </PHP>
  
-The reset is not limited to new scopes but any new by-value reference:+The reset is not limited to new function scopes but any new by-value reference:
  
 <PHP> <PHP>
Line 82: Line 94:
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
  
-This change is not backward compatible; code relying on the next element index being +This change is not backward compatible; code relying on the "auto-increment" value being 
-remembered between copies of copy-on-write will break. However, the proposed change +remembered between copies of copy-on-write will break. However, the proposed change should 
-should be considered a bug-fix, rather than a behavior change. In fact, it offers +be considered a bug-fix, rather than a behavior changeit offers protection against 
-protection against ''array''-lists that were misused with ''unset()'' instead of +''array''-lists that were misused with ''unset()'' instead of ''array_pop/_splice/_shift'' 
-''array_pop/_splice/_shift''.+and thus will only affect code that is already a candidate for improvements. Furthermore, 
 +the "auto-increment" value is copied inconsistently, when the ''array'' is empty: 
 + 
 +<PHP> 
 +$a = [0, 1]; 
 +unset($a[1]); 
 +$b = $a; 
 +$b[] = 2; 
 +// $b is [0 => 0, 2 => 2] 
 + 
 +$a = [0, 1]; 
 +unset($a[0], $a[1]); 
 +$b = $a; 
 +$b[] = 2; 
 +// $b is [0 => 2], rather than [2 => 2] 
 +</PHP> 
 + 
 +The proposed change would make the behavior consistent and safer.
  
 ===== Proposed PHP Version(s) ===== ===== Proposed PHP Version(s) =====
  
-Next PHP minor version+7.4
  
 ===== Proposed Voting Choices ===== ===== Proposed Voting Choices =====
Line 96: Line 125:
 Vote will require 2/3 majority Vote will require 2/3 majority
  
 +===== References  =====
 +
 +  * [[https://externals.io/message/105992|Pre-vote discussion on externals.io]]
rfc/normalize-array-auto-increment-on-copy-on-write.1560980322.txt.gz · Last modified: 2019/06/19 21:38 by wesnetmo