Hey folks,
I've written up an RFC/Patch to gauge interest and get feedback on the
addition of a combined comparison (aka: spaceship) operator.
You can see the RFC at:
https://wiki.php.net/rfc/combined-comparison-operator
This adds a new operator "(expr) <=> (expr)" that returns 0 if both
operands are equal, 1 if the left is greater, and -1 if the right is
greater.
It works with all types (just as well as <, <=, >=, > work) and is great
for usort()
callbacks for example.
Code available here (against 5.6):
https://github.com/dshafik/php-src/compare/add-spaceship-operator
I'd love to get this into 5.6, not sure if we hit feature freeze yet.
Also, not sure if it needs 2/3 majority, but assumed so as pow did?
Thoughts?
If there is interest, I'll start adding tests. They should be fairly
trivial.
- Davey
This adds a new operator "(expr) <=> (expr)" that returns 0 if both
operands are equal, 1 if the left is greater, and -1 if the right is
greater.It works with all types (just as well as <, <=, >=, > work) and is great
forusort()
callbacks for example.
It's useful and cool, and adds an awesome new operator name
((T_SPACESHIP <=> T_PAAMAYIM_NEKUDOTAYIM) === 1), but would it be used
often enough to justify addition?
--
Andrea Faulds
http://ajf.me/
Hi Davey,
I've written up an RFC/Patch to gauge interest and get feedback on the
addition of a combined comparison (aka: spaceship) operator.You can see the RFC at: https://wiki.php.net/rfc/
combined-comparison-operatorThis adds a new operator "(expr) <=> (expr)" that returns 0 if both
operands are equal, 1 if the left is greater, and -1 if the right is
greater.It works with all types (just as well as <, <=, >=, > work) and is great
forusort()
callbacks for example.Code available here (against 5.6): https://github.com/dshafik/
php-src/compare/add-spaceship-operatorI'd love to get this into 5.6, not sure if we hit feature freeze yet.
Also, not sure if it needs 2/3 majority, but assumed so as pow did?Thoughts?
If there is interest, I'll start adding tests. They should be fairly
trivial.
Interesting shortcut operator.
I feel closure function is for the task.
I would vote 0, but close to -1 since it's only useful for sorting.
Is there any other use cases?
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Davey,
I've written up an RFC/Patch to gauge interest and get feedback on the
addition of a combined comparison (aka: spaceship) operator.You can see the RFC at: https://wiki.php.net/rfc/
combined-comparison-operatorThis adds a new operator "(expr) <=> (expr)" that returns 0 if both
operands are equal, 1 if the left is greater, and -1 if the right is
greater.It works with all types (just as well as <, <=, >=, > work) and is great
forusort()
callbacks for example.Code available here (against 5.6): https://github.com/dshafik/
php-src/compare/add-spaceship-operatorI'd love to get this into 5.6, not sure if we hit feature freeze yet.
Also, not sure if it needs 2/3 majority, but assumed so as pow did?Thoughts?
If there is interest, I'll start adding tests. They should be fairly
trivial.Interesting shortcut operator.
I feel closure function is for the task.
I would vote 0, but close to -1 since it's only useful for sorting.
Is there any other use cases?Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Yasuo,
Sorting is definitely it's most compelling use. It cuts down on
potentially quite a bit of code:
function ($left, $right) {
if ($left[1] == $right[1]) {
return 0;
}
if ($left[1] > $right[1]) {
return 1;
}
if ($left[1] < $right[1]) {
return -1;
}
}
or (as per the RFC):
function ($left, $right) {
return $left[1] <=> $right[1];
}
Hi Davey,
I've written up an RFC/Patch to gauge interest and get feedback on the
addition of a combined comparison (aka: spaceship) operator.You can see the RFC at: https://wiki.php.net/rfc/
combined-comparison-operatorThis adds a new operator "(expr) <=> (expr)" that returns 0 if both
operands are equal, 1 if the left is greater, and -1 if the right is
greater.It works with all types (just as well as <, <=, >=, > work) and is great
forusort()
callbacks for example.Code available here (against 5.6): https://github.com/dshafik/
php-src/compare/add-spaceship-operatorI'd love to get this into 5.6, not sure if we hit feature freeze yet.
Also, not sure if it needs 2/3 majority, but assumed so as pow did?Thoughts?
If there is interest, I'll start adding tests. They should be fairly
trivial.Interesting shortcut operator.
I feel closure function is for the task.
I would vote 0, but close to -1 since it's only useful for sorting.
Is there any other use cases?Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.netYasuo,
Sorting is definitely it's most compelling use. It cuts down on potentially quite a bit of code:
function ($left, $right) {
if ($left[1] == $right[1]) {
return 0;
}if ($left[1] > $right[1]) {
return 1;
}if ($left[1] < $right[1]) {
return -1;
}
}or (as per the RFC):
function ($left, $right) {
return $left[1] <=> $right[1];
}--
The only real case I see for this is to save some boilerplate when dealing with arrays. Strings have strcmp()
, numbers have subtraction and when you’re sorting objects, you probably want to be doing the comparison on some string/numeric property.
If you really need the -1/0/1 return value (sorting functions don’t), then wrap the strcmp/subtraction in a trivial sign() function.
Simon Welsh
Admin of http://simon.geek.nz/
function ($left, $right) {
if ($left[1] == $right[1]) {
return 0;
}if ($left[1] > $right[1]) { return 1; } if ($left[1] < $right[1]) { return -1; }
}
or (as per the RFC):
function ($left, $right) {
return $left[1] <=> $right[1];
}
while that example is overly nice - in real world outside a usort
callback the consumer of the function in most cases still has to do the
three if cases to use the result. So in practical terms it is limited to
usort()
and then it is a custom operator people reading the code most
likely have to lookup. Typically in PHP we try to have identifiers which
can be found via Google, Google doesn't handle "special" characters
well.
johannes
Davey Shafik davey@php.net wrote:
This adds a new operator "(expr) <=> (expr)" that returns 0 if both
operands are equal, 1 if the left is greater, and -1 if the right is
greater.It works with all types (just as well as <, <=, >=, > work) and is great
forusort()
callbacks for example.
Why not using $a - $b
instead of $a <=> $b
?
Simon J Welsh simon@simon.geek.nz wrote:
The only real case I see for this is to save some boilerplate when
dealing with arrays. Strings havestrcmp()
, numbers have subtraction
And when you’re sorting objects, you probably want to be doing
the comparison on some string/numeric property.
Agreed! It would make more sense to write a comparison function for arrays/objects.
Best regards
Christian
On Thu, Feb 13, 2014 at 3:19 PM, Christian Stoller stoller@leonex.dewrote:
Davey Shafik davey@php.net wrote:
This adds a new operator "(expr) <=> (expr)" that returns 0 if both
operands are equal, 1 if the left is greater, and -1 if the right is
greater.It works with all types (just as well as <, <=, >=, > work) and is great
forusort()
callbacks for example.Why not using
$a - $b
instead of$a <=> $b
?
This only works on numbers, and integers in particular, because of how the
result of a comparison function is cast.
For example, 0.4f - 0.5f
equals -0.1f
but gets cast to 0
when it's
converted to a long value.
See also: http://lxr.php.net/xref/PHP_5_6/ext/standard/array.c#597
Simon J Welsh simon@simon.geek.nz wrote:
The only real case I see for this is to save some boilerplate when
dealing with arrays. Strings havestrcmp()
, numbers have subtraction
And when you're sorting objects, you probably want to be doing
the comparison on some string/numeric property.Agreed! It would make more sense to write a comparison function for
arrays/objects.Best regards
Christian
--
Tjerk
Davey Shafik davey@php.net wrote:
This adds a new operator "(expr) <=> (expr)" that returns 0 if both
operands are equal, 1 if the left is greater, and -1 if the right is
greater.It works with all types (just as well as <, <=, >=, > work) and is great
forusort()
callbacks for example.Why not using
$a - $b
instead of$a <=> $b
?Simon J Welsh simon@simon.geek.nz wrote:
The only real case I see for this is to save some boilerplate when
dealing with arrays. Strings havestrcmp()
, numbers have subtraction
And when you’re sorting objects, you probably want to be doing
the comparison on some string/numeric property.Agreed! It would make more sense to write a comparison function for arrays/objects.
Best regards
Christian
This operator DOES work on arrays/objects. The fact it also works on
scalar values is a bonus if that's how you want to look at it :P
- Davey
Hi David,
Thanks for this proposal.
Davey Shafik davey@php.net wrote:
This adds a new operator "(expr) <=> (expr)" that returns 0 if both
operands are equal, 1 if the left is greater, and -1 if the right is
greater.It works with all types (just as well as <, <=, >=, > work) and is great
forusort()
callbacks for example.Why not using
$a - $b
instead of$a <=> $b
?Simon J Welsh simon@simon.geek.nz wrote:
The only real case I see for this is to save some boilerplate when
dealing with arrays. Strings havestrcmp()
, numbers have subtraction
And when you’re sorting objects, you probably want to be doing
the comparison on some string/numeric property.Agreed! It would make more sense to write a comparison function for
arrays/objects.Best regards
ChristianThis operator DOES work on arrays/objects. The fact it also works on
scalar values is a bonus if that's how you want to look at it :P
This new operator doea not look too useful to me but here is one comment
about objects handling:
It compares only values, seems to be the only solution but the actual usage
for that is rather inexistent as it compares apples and pears, or am I
missing something?
Cheers,
Pierre
Hi David,
Thanks for this proposal.
Davey Shafik davey@php.net wrote:
This adds a new operator "(expr) <=> (expr)" that returns 0 if both
operands are equal, 1 if the left is greater, and -1 if the right is
greater.It works with all types (just as well as <, <=, >=, > work) and is great
forusort()
callbacks for example.Why not using
$a - $b
instead of$a <=> $b
?Simon J Welsh simon@simon.geek.nz wrote:
The only real case I see for this is to save some boilerplate when
dealing with arrays. Strings havestrcmp()
, numbers have subtraction
And when you’re sorting objects, you probably want to be doing
the comparison on some string/numeric property.Agreed! It would make more sense to write a comparison function for
arrays/objects.Best regards
ChristianThis operator DOES work on arrays/objects. The fact it also works on
scalar values is a bonus if that's how you want to look at it :PThis new operator doea not look too useful to me but here is one comment
about objects handling:It compares only values, seems to be the only solution but the actual usage
for that is rather inexistent as it compares apples and pears, or am I
missing something?Cheers,
Pierre
So, this behavior can definitely be changed — preserving the current
behavior of == for the 0 value, and then we can go two different ways
for 1/-1:
- Compare only like-for-like keys, ignoring extra keys
- Compare like-for-like keys, and count the number of additional keys
are being great. So: if they match on all common keys, but left has 3
additional keys, and right has 4, right is greater than left.
It's definitely tough to get the semantics right. But: the behavior is
also currently identical to $obj <= $obj2, etc. I felt that consistency
was most important.
The logical next step with this operator is to add a "Comparable"
"interface" like ruby (not saying it has to be an interface, magic
method also works), that allows the objects themselves to define the
comparison behavior, so you could do:
class Foo {
function __compare($right) {
// logic here
}
}
$left = new Foo;
$right = new Foo;
$left <=> $right; // Same as $left->__compare($right);
So, this behavior can definitely be changed — preserving the current
behavior of == for the 0 value, and then we can go two different ways for
1/-1:
Btw, I forgot to mention that for equality comparisons, we have the
instance hash function, which was created exactly for that.
So, this behavior can definitely be changed — preserving the current
behavior of == for the 0 value, and then we can go two different ways for
1/-1:Btw, I forgot to mention that for equality comparisons, we have the
instance hash function, which was created exactly for that.
Right, that's what I mean by preserving the behavior of ==
Hi David,
Thanks for this proposal.
Davey Shafik davey@php.net wrote:
This adds a new operator "(expr) <=> (expr)" that returns 0 if both
operands are equal, 1 if the left is greater, and -1 if the right is
greater.It works with all types (just as well as <, <=, >=, > work) and is
great
forusort()
callbacks for example.Why not using
$a - $b
instead of$a <=> $b
?Simon J Welsh simon@simon.geek.nz wrote:
The only real case I see for this is to save some boilerplate when
dealing with arrays. Strings havestrcmp()
, numbers have subtraction
And when you're sorting objects, you probably want to be doing
the comparison on some string/numeric property.Agreed! It would make more sense to write a comparison function for
arrays/objects.
Best regards
ChristianThis operator DOES work on arrays/objects. The fact it also works on
scalar values is a bonus if that's how you want to look at it :P
This new operator doea not look too useful to me but here is one comment
about objects handling:It compares only values, seems to be the only solution but the actual
usage
for that is rather inexistent as it compares apples and pears, or am I
missing something?Cheers,
PierreSo, this behavior can definitely be changed -- preserving the current
behavior of == for the 0 value, and then we can go two different ways for
1/-1:
- Compare only like-for-like keys, ignoring extra keys
- Compare like-for-like keys, and count the number of additional keys are
being great. So: if they match on all common keys, but left has 3 additional
keys, and right has 4, right is greater than left.It's definitely tough to get the semantics right. But: the behavior is also
currently identical to $obj <= $obj2, etc. I felt that consistency was most
important.The logical next step with this operator is to add a "Comparable"
"interface" like ruby (not saying it has to be an interface, magic method
also works), that allows the objects themselves to define the comparison
behavior, so you could do:class Foo {
function __compare($right) {
// logic here
}
}$left = new Foo;
$right = new Foo;$left <=> $right; // Same as $left->__compare($right);
Please, don't.
Comparable has already been discussed many times, and has its own RFC and topic.
https://wiki.php.net/rfc/comparable
Don't mix things.
Comparable is another idea than adding a new operator.
Julien
Why not using
$a - $b
instead of$a <=> $b
?Simon J Welsh simon@simon.geek.nz wrote:
The only real case I see for this is to save some boilerplate when
dealing with arrays. Strings havestrcmp()
, numbers have subtraction
And when you’re sorting objects, you probably want to be doing
the comparison on some string/numeric property.Agreed! It would make more sense to write a comparison function for arrays/objects.
Best regards
ChristianThis operator DOES work on arrays/objects. The fact it also works on
scalar values is a bonus if that's how you want to look at it :P
- Davey
That's why I said, it would make more sense to add a new function for comparing arrays and objects.
Why adding a new comparison operator if we could achieve the same with one or two additional functions?
And I am not sure, if this is not already possible nowadays.
For arrays you could do: array_sum($array1) - array_sum($array2)
And for objects you can define a "sum" method on your objects or a trait e.g.
trait SummableTrait {
public function sum() {
$sum = 0;
foreach (get_object_vars($this) as $value) {
$sum += $value;
}
return $sum;
}
}
You only have to use this trait in your classes and then you can do: $object1->sum() - $object2->sum()
Et voilà :-)
Christian
On Fri, 14 Feb 2014 11:18:53 +0400, Christian Stoller stoller@leonex.de
wrote:
Why not using
$a - $b
instead of$a <=> $b
?Simon J Welsh simon@simon.geek.nz wrote:
The only real case I see for this is to save some boilerplate when
dealing with arrays. Strings havestrcmp()
, numbers have subtraction
And when you’re sorting objects, you probably want to be doing
the comparison on some string/numeric property.Agreed! It would make more sense to write a comparison function for
arrays/objects.Best regards
ChristianThis operator DOES work on arrays/objects. The fact it also works on
scalar values is a bonus if that's how you want to look at it :P
- Davey
That's why I said, it would make more sense to add a new function for
comparing arrays and objects.
Why adding a new comparison operator if we could achieve the same with
one or two additional functions?And I am not sure, if this is not already possible nowadays.
For arrays you could do:
array_sum($array1) - array_sum($array2)
And for objects you can define a "sum" method on your objects or a trait
e.g.trait SummableTrait {
public function sum() {
$sum = 0;
foreach (get_object_vars($this) as $value) {
$sum += $value;
}
return $sum;
}
}You only have to use this trait in your classes and then you can do:
$object1->sum() - $object2->sum()
Et voilà :-)
Christian
Hi,
DateTime is the problem here
It works with all types (just as well as <, <=, >=, > work) and is great
forusort()
callbacks for example.I'd love to get this into 5.6, not sure if we hit feature freeze yet.
Also, not sure if it needs 2/3 majority, but assumed so as pow did?Thoughts?
I like shorter sort callbacks, but I think a function taking in "any"
data type would be more effective since you could in some cases even
shorten it to this:
usort($arr, 'magic_compare');
Don't take the name at face value though ;)
Cheers
--
Jordi Boggiano
@seldaek - http://nelm.io/jordi
Hey folks,
Hello Davey :-),
Thanks for the proposal.
I've written up an RFC/Patch to gauge interest and get feedback on the
addition of a combined comparison (aka: spaceship) operator.You can see the RFC at:
https://wiki.php.net/rfc/combined-comparison-operatorThis adds a new operator "(expr) <=> (expr)" that returns 0 if both
operands are equal, 1 if the left is greater, and -1 if the right is
greater.It works with all types (just as well as <, <=, >=, > work) and is
great forusort()
callbacks for example.
Am I the only one who think that<=>
is already a Mathematical
operator standing for the “equivalence”?
PHP already uses=>
as a key/value matching operator for pairs in an
array, whereas in Math., it is the “implies” operator. Right, we may
still introduce the==>
later. But I can't see<=>
becoming<==>
or even<===>
.
Moreover, as Jordi and others have suggested, a simple PHP function will
do the job, and much better. A -1/0/1 result depends on the compared
values and the interpretation of these latters: do we compare the number
of pairs in an array, just the keys, just the values, do we also compare
the type…? To much context for a single unambiguous operator. One or
more dedicated functions (one per type maybe) is a more realistic way in
my opinion.
Thoughts?
Cheers :-).
--
Ivan Enderlin
Developer of Hoa
http://hoa-project.net/
PhD. student at DISC/Femto-ST (Vesontio) and INRIA (Cassis)
http://disc.univ-fcomte.fr/ and http://www.inria.fr/
Member of HTML and WebApps Working Group of W3C
http://w3.org/
Davey Shafik wrote (on 13/02/2014):
I'd love to get this into 5.6, not sure if we hit feature freeze yet.
I believe the decision was that to be part of PHP 5.6, the RFC needed to
have been introduced before the first alpha, and voting concluded before
the first beta.
PHP 5.6 Alpha 2 was released yesterday, so no new RFCs should be
accepted under that rule.
Regards,
Rowan Collins
[IMSoP]