rfc:combined-comparison-operator

This is an old revision of the document!


PHP RFC: Combined Comparison (Spaceship) Operator

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 <, <=, >=, >.

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.

This operator (<=>) is often called the spaceship operator, and works on all standard PHP values.

Great for use with usort() callbacks.

It uses the existing in compare_function that underlies the other comparison operators.

// Integers
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1
 
// Floats
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1
 
// Strings
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1
 
echo "a" <=> "aa"; // -1
echo "zz" <=> "aa"; // 1
 
// Arrays
echo [] <=> []; // 0
echo [1, 2, 3] <=> [1, 2, 3]; // 0
echo [1, 2, 3] <=> []; // 1
echo [1, 2, 3] <=> [1, 2, 1]; // 1
echo [1, 2, 3] <=> [1, 2, 4]; // -1
 
// Objects
$a = (object) ["a" => "b"]; 
$b = (object) ["a" => "b"]; 
echo $a <=> $b; // 0
 
$a = (object) ["a" => "b"]; 
$b = (object) ["a" => "c"]; 
echo $a <=> $b; // -1
 
$a = (object) ["a" => "c"]; 
$b = (object) ["a" => "b"]; 
echo $a <=> $b; // 1
 
// only values are compared
$a = (object) ["a" => "b"]; 
$b = (object) ["b" => "b"]; 
echo $a <=> $b; // 0

Usort Example:

if (($handle = fopen("people.csv", "r")) !== FALSE) {
    while (($row = fgetcsv($handle, 1000, ",")) !== FALSE) {
         $data[] = $row;
    }
    fclose($handle);
}
 
// Sort by last name:
usort($data, function ($left, $right) {
     return $left[1] <=> $right[1];
});

Backward Incompatible Changes

This introduces no backwards incompatible changes.

Proposed PHP Version(s)

Next PHP 5.x

Impact to Existing Extensions

May need some additional changes for support with the new operator overloading and GMP.

New Constants

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

All existing comparison operators, particularly <= are unaffected by this addition.

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.

Proposed Voting Choices

  • Include in PHP 5.6
  • Include in PHP 5.6+1
  • Do not include

A two third majority is required for acceptance.

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

rfc/combined-comparison-operator.1392265611.txt.gz · Last modified: 2017/09/22 13:28 (external edit)