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
Last revisionBoth sides next revision
rfc:combined-comparison-operator [2014/02/14 16:47] daveyrfc:combined-comparison-operator [2016/05/16 22:10] – Remove infamously incorrect comment ajf
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.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1