rfc:combined-comparison-operator

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:combined-comparison-operator [2014/02/14 16:47] daveyrfc:combined-comparison-operator [2017/09/22 13:28] (current) – external edit 127.0.0.1
Line 1: Line 1:
  
 ====== PHP RFC: Combined Comparison (Spaceship) Operator ====== ====== PHP RFC: Combined Comparison (Spaceship) Operator ======
-  * Version: 0.1 +  * Version: 0.2.1 
-  * Date: 2014-02-12 +  * Date: 2014-02-12 (original), 2015-01-19 (v0.2) 
-  * Author: Davey Shafikdavey@php.net +  * Authors: Davey Shafik <davey@php.net>, Andrea Faulds <ajf@ajf.me>, Stas Malyshev <stas@php.net> 
-  * Status: Draft+  * Status: Accepted
   * First Published at: http://wiki.php.net/rfc/combined-comparison-operator   * First Published at: http://wiki.php.net/rfc/combined-comparison-operator
  
 ===== Introduction ===== ===== Introduction =====
  
-This RFC adds a new operator for combined comparison. Similar to ''strcmp()'' or ''version_compare()'' in behavior, but it can be used on all generic PHP values with the same semantics as ''%%<, <=, >=, >%%''.+This RFC adds a new operator for combined comparison. Similar to ''strcmp()'' or ''version_compare()'' in behavior, but it can be used on all generic PHP values with the same semantics as ''%%<, <=, ==, >=, >%%''.
  
 ===== Proposal ===== ===== Proposal =====
  
-Add a new operator ''(expr) %%<=>%% (expr)'',  it returns 0 if both operands are equal, 1 if the left is greater, and -1 if the right is greater.+Add a new operator ''(expr) %%<=>%% (expr)'',  it returns 0 if both operands are equal, 1 if the left is greater, and -1 if the right is greater. It uses exactly the same comparison rules as used by our existing comparison operators: ''%%<, <=, ==, >=%%'' and ''>''. (See the manual for [[http://php.net/manual/en/language.operators.comparison.php|details]])
  
-This operator (''%%<=>%%'') is often called the spaceship operator, and works on all standard PHP values.+This [[https://en.wikipedia.org/wiki/Three-way_comparison|"three-way comparison operator"]], also known as the "spaceship operator" (a common name in other languages), works on all standard PHP values. It exists in other languages: [[http://perldoc.perl.org/perlop.html#Equality-Operators|Perl]], [[http://ruby-doc.org/core-1.9.3/Comparable.html|Ruby]], and Groovy.
  
-Great for use with ''usort()'' callbacks.+For [[http://perldoc.perl.org/perlop.html#Operator-Precedence-and-Associativity|consistency with Perl]], it has the same precedence as ''=='' and ''!=''.
  
-It uses the existing in ''compare_function'' that underlies the other comparison operators.+It is implemented by using the result of the existing internal ''compare_function'' that underlies the other comparison operators. The existing comparison operators could be considered mere shorthands for ''%%<=>%%'': 
 + 
 +^ operator          ^ ''%%<=>%%'' equivalent     ^ 
 +| ''$a < $b''       | ''%%($a <=> $b) === -1%%''
 +| ''%%$a <= $b%%''  | ''%%($a <=> $b) === -1 || ($a <=> $b) === 0%%''
 +| ''$a == $b''      | ''%%($a <=> $b) === 0%%'' 
 +| ''$a != $b''      | ''%%($a <=> $b) !== 0%%'' 
 +| ''%%$a >= $b%%''  | ''%%($a <=> $b) === 1 || ($a <=> $b) === 0%%''
 +| ''$a > $b''       | ''%%($a <=> $b) === 1%%'' 
 + 
 +Here are some examples of its behaviour:
  
 <code php> <code php>
Line 60: Line 70:
 echo $a <=> $b; // 1 echo $a <=> $b; // 1
  
-// only values are compared 
 $a = (object) ["a" => "b"];  $a = (object) ["a" => "b"]; 
 $b = (object) ["b" => "b"];  $b = (object) ["b" => "b"]; 
Line 81: Line 90:
 }); });
 </code> </code>
 +
 +===== Usefulness =====
 +
 +It makes writing ordering callbacks for use with ''usort()'' easier. Commonly, users write poor or incorrect ordering functions like this one:
 +
 +<code php>
 +function order_func($a, $b) {
 +    return $a >= $b;
 +}
 +</code>
 +
 +When users do write correct ordering functions, they have to be quite verbose:
 +
 +<code php>
 +function order_func($a, $b) {
 +    return ($a < $b) ? -1 : (($a > $b) ? 1 : 0);
 +}
 +</code>
 +
 +This becomes particularly bad when sorting by multiple columns lexicographically.
 +
 +With this operator, you can easily write proper ordering functions, like this one:
 +
 +<code php>
 +function order_func($a, $b) {
 +    return $a <=> $b;
 +}
 +</code>
 +
 +Sorting by multiple columns is simpler now, too:
 +
 +<code php>
 +function order_func($a, $b) {
 +    return [$a->x, $a->y, $a->foo] <=> [$b->x, $b->y, $b->foo];
 +}
 +</code>
 +
 +Or:
 +
 +<code php>
 +function order_func($a, $b) {
 +    return ($a->$x <=> $b->x) ?: ($a->y <=> $b->y) ?: ($a->foo <=> $b->foo);
 +}
 +</code>
 +
 +It is also useful in some other contexts.
  
 ===== Backward Incompatible Changes ===== ===== Backward Incompatible Changes =====
Line 88: Line 143:
 ===== Proposed PHP Version(s) ===== ===== Proposed PHP Version(s) =====
  
-Next PHP 5.+The next major version of PHP, currently PHP 7.0.
- +
-===== Impact to Existing Extensions ===== +
- +
-May need some additional changes for support with the new operator overloading and GMP.+
  
 ===== New Constants ===== ===== New Constants =====
  
 A ''T_SPACESHIP'' constant for use with ext/tokenizer has been added. A ''T_SPACESHIP'' constant for use with ext/tokenizer has been added.
- 
-===== Open Issues ===== 
- 
-  * Further changes may be required to support operator overloading/GMP 
-  * Requires tests 
  
 ===== Unaffected PHP Functionality ===== ===== Unaffected PHP Functionality =====
  
-All existing comparison operators, particularly ''<='' are unaffected by this addition.+All existing comparison operators are unaffected by this addition.
  
 ===== Future Scope ===== ===== Future Scope =====
  
-  * Could also add a ''%%<==>%%'' operator for strict comparisons. Current thinking is it would return ''false'' with type mismatch, similar to ''strpos()''. Strict return checking will be required.+None.
  
-===== Proposed Voting Choices =====+===== Vote =====
  
-  * Include in PHP 5.6 +Voting started on 2015-02-02 and will to end on 2015-02-16. As this adds to the PHP language (and hence affects the PHP language specification) a 2/3 majority is required for acceptance. It is a Yes/No vote to accepting the RFC and merging the patch
-  Include in PHP 5.6+1 + 
-  Do not include+<doodle title="Accept the Combined Comparison (Spaceship) Operator RFC and merge patch into master?" auth="stas" voteType="single" closed="true"> 
 +   Yes 
 +   No 
 +</doodle>
  
-A two third majority is required for acceptance. 
  
 ===== Patches and Tests ===== ===== Patches and Tests =====
  
-Patch against 5.6 can be seen in this branch on github: https://github.com/dshafik/php-src/compare/add-spaceship-operator +A patch targeting php-src master is here: https://github.com/php/php-src/pull/1007 
 + 
 +There is not yet a language specification patch. 
 + 
 +Shafik's original patch against 5.6 was here: https://github.com/dshafik/php-src/compare/add-spaceship-operator  
 + 
 +===== Changelog ===== 
 + 
 +  * v0.2.1 - Clarity on type-juggling behaviour and relation to other comparison operators 
 +  * v0.2 - Updated, retargeted to PHP 7 by Andrea 
 +  * v0.1 - Initial version by Shafik
rfc/combined-comparison-operator.1392396455.txt.gz · Last modified: 2017/09/22 13:28 (external edit)