Good morning,
This is a reboot of Davey Shafik’s RFC (with permission). After recent discussions about sort functions, I was inspired to bring this back up, as I think it would be a useful feature.
The RFC is here: https://wiki.php.net/rfc/combined-comparison-operator
Thanks!
Andrea Faulds
http://ajf.me/
Good morning,
This is a reboot of Davey Shafik’s RFC (with permission). After recent discussions about sort functions, I was inspired to bring this back up, as I think it would be a useful feature.
The RFC is here: https://wiki.php.net/rfc/combined-comparison-operator
I am all for it, but just so we don't end up with yet another
T_PAAMAYIM_NEKUDOTAYIM
can we please not call this T_SPACESHIP? It
sounds fun now but future generations will hate us.
Rather use T_COMBINED_COMPARISON or such?
Cheers
--
Jordi Boggiano
@seldaek - http://nelm.io/jordi
Hi Jordi,
Good morning,
This is a reboot of Davey Shafik’s RFC (with permission). After recent discussions about sort functions, I was inspired to bring this back up, as I think it would be a useful feature.
The RFC is here: https://wiki.php.net/rfc/combined-comparison-operator
I am all for it, but just so we don't end up with yet another
T_PAAMAYIM_NEKUDOTAYIM
can we please not call this T_SPACESHIP? It sounds fun now but future generations will hate us.Rather use T_COMBINED_COMPARISON or such?
It’d be possible. On the other hand, this isn’t just an in-joke: the “spaceship operator” is a common name for it in other languages, and if you google it you will actually find information about the operator.
Plus, it’s fun.
Andrea Faulds
http://ajf.me/
Hi Jordi,
Good morning,
This is a reboot of Davey Shafik’s RFC (with permission). After recent discussions about sort functions, I was inspired to bring this back up, as I think it would be a useful feature.
The RFC is here: https://wiki.php.net/rfc/combined-comparison-operator
I am all for it, but just so we don't end up with yet another
T_PAAMAYIM_NEKUDOTAYIM
can we please not call this T_SPACESHIP? It sounds fun now but future generations will hate us.Rather use T_COMBINED_COMPARISON or such?
It’d be possible. On the other hand, this isn’t just an in-joke: the “spaceship operator” is a common name for it in other languages, and if you google it you will actually find information about the operator.
Plus, it’s fun.
Fair enough, it's not as bad, but I thought it should be raised.
Cheers
--
Jordi Boggiano
@seldaek - http://nelm.io/jordi
The RFC is here: https://wiki.php.net/rfc/combined-comparison-operator
I like it.
The RFC does not say what the precedence is to be. Could I suggest that it be
the same as ''== != === !== <>'' - which keeps it consistent with Perl.
--
Alain Williams
Linux/GNU Consultant - Mail systems, Web sites, Networking, Programmer, IT Lecturer.
+44 (0) 787 668 0256 http://www.phcomp.co.uk/
Parliament Hill Computers Ltd. Registration Information: http://www.phcomp.co.uk/contact.php
#include <std_disclaimer.h
Hi Alain,
The RFC is here: https://wiki.php.net/rfc/combined-comparison-operator
I like it.
The RFC does not say what the precedence is to be. Could I suggest that it be
the same as ''== != === !== <>'' - which keeps it consistent with Perl.
It has the same precedence as the other comparison operators, it’s non-associative.
Thanks.
--
Andrea Faulds
http://ajf.me/
Hi Alain,
The RFC is here: https://wiki.php.net/rfc/combined-comparison-operator
I like it.
The RFC does not say what the precedence is to be. Could I suggest that it be
the same as ''== != === !== <>'' - which keeps it consistent with Perl.It has the same precedence as the other comparison operators, it’s non-associative.
Sorry to be a persistent pain, but PHP has 2 sets of comparison operators with
different precedence:
''< <= > >=''
''== != === !== <>''
I think that the RFC should clearly state that spaceship joins the 2nd set of
operators in the precedence table. The introduction kind of hints that it would
join the first lot -- but that would be inconsistent with Perl.
http://uk1.php.net/manual/en/language.operators.precedence.php
--
Alain Williams
Linux/GNU Consultant - Mail systems, Web sites, Networking, Programmer, IT Lecturer.
+44 (0) 787 668 0256 http://www.phcomp.co.uk/
Parliament Hill Computers Ltd. Registration Information: http://www.phcomp.co.uk/contact.php
#include <std_disclaimer.h
Hi Alain,
I like it.
The RFC does not say what the precedence is to be. Could I suggest that it be
the same as ''== != === !== <>'' - which keeps it consistent with Perl.It has the same precedence as the other comparison operators, it’s non-associative.
Sorry to be a persistent pain, but PHP has 2 sets of comparison operators with
different precedence:''< <= > >=''
''== != === !== <>''
I think that the RFC should clearly state that spaceship joins the 2nd set of
operators in the precedence table. The introduction kind of hints that it would
join the first lot -- but that would be inconsistent with Perl.http://uk1.php.net/manual/en/language.operators.precedence.php
Ah, I get you. I’m making it the same precedence as Perl (same as == and !=), then. I’ve updated the RFC and will update the patch.
Thanks.
Andrea Faulds
http://ajf.me/
Hi Andrea,
Good morning,
This is a reboot of Davey Shafik’s RFC (with permission). After recent
discussions about sort functions, I was inspired to bring this back up, as
I think it would be a useful feature.The RFC is here: https://wiki.php.net/rfc/combined-comparison-operator
I can only think of how many times I would have liked to have this over the
last decade. Seems very straight forward and would be a perfect addition
for 7.
Good morning,
This is a reboot of Davey Shafik’s RFC (with permission). After recent
discussions about sort functions, I was inspired to bring this back up, as
I think it would be a useful feature.The RFC is here: https://wiki.php.net/rfc/combined-comparison-operator
Thanks!
I like the idea behind this (exposing internal compare_function), but I
don't want to have an extra operator for a minor use case. Please just
introduce a function instead.
The operator is also less clear ... if I see "$a <=> $b" and do not happen
to be familiar with another language implementing this operator, I won't
have any idea what it does (the closest thing <=> could be is the
equivalence operator from logic, and that's not the case here). On the
other hand something like compare($a, $b) is pretty obvious. If there is
concern about clashing with user-defined functions, lets namespace it.
A function can also be directly used as a callback. Furthermore a function
would fit in well with existing comparison functions like strcmp etc.
Nikita
Nikita
Hey Nikita,
I like the idea behind this (exposing internal compare_function), but I don't want to have an extra operator for a minor use case. Please just introduce a function instead.
I originally wanted a function, but an operator has some advantages. There’s no backwards-compatibility issues from function name conflicts (nor do we have to break with tradition and use a namespace despite everything else not having one). The syntax is similar to other comparisons: we don’t have lt(), gt(), lt_or_eq(), gt_or_eq(), eq() and not_eq(), we have <, >, <=, >=, == and !=. Why, then, should we have cmp() or compare()? We get to fix one of C’s mistakes here, in that C (unlike FORTRAN of all things) failed to provide a three-way comparison operation despite it being useful and often available natively. <=> has a certain brevity and is familiar to Ruby and Perl users.
Plus, it looks cool and has a cool name (not really an argument, I know).
Still, there is a case for a function, but I’m trying for an operator for now. I quite like how this feature makes multi-item comparisons much simpler.
--
Andrea Faulds
http://ajf.me/
Hey Nikita,
I like the idea behind this (exposing internal compare_function), but I don't want to have an extra operator for a minor use case. Please just introduce a function instead.
I originally wanted a function, but an operator has some advantages. There’s no backwards-compatibility issues from function name conflicts (nor do we have to break with tradition and use a namespace despite everything else not having one). The syntax is similar to other comparisons: we don’t have lt(), gt(), lt_or_eq(), gt_or_eq(), eq() and not_eq(), we have <, >, <=, >=, == and !=. Why, then, should we have cmp() or compare()? We get to fix one of C’s mistakes here, in that C (unlike FORTRAN of all things) failed to provide a three-way comparison operation despite it being useful and often available natively. <=> has a certain brevity and is familiar to Ruby and Perl users.Plus, it looks cool and has a cool name (not really an argument, I know).
Still, there is a case for a function, but I’m trying for an operator for now. I quite like how this feature makes multi-item comparisons much simpler.
--
Andrea Faulds
http://ajf.me/
This looks potentially quite useful, especially for multi-stage
comparisons as you note. Mainly it would mean I don't have to remember
which direction is positive or negative, as I can never get that right
without looking it up. :-)
The examples say nothing about mixing types, though. Eg, what would
these return:
return 0 <=> "0"
return "" <=> 0
return 1 <=> [1, 2, 3]
Ignoring object property names and going by the order of the property
definition seems like asking for trouble, too.
There may be easy logical answers to the above given PHP's existing type
juggling, but they should be called out explicitly in both the RFC and
in any subsequent documentation.
--Larry Garfield
Hi Larry,
This looks potentially quite useful, especially for multi-stage comparisons as you note. Mainly it would mean I don't have to remember which direction is positive or negative, as I can never get that right without looking it up. :-)
Glad you like it. I, too, sometimes have trouble remembering what direction it goes in.
The examples say nothing about mixing types, though. Eg, what would these return:
return 0 <=> "0"
return "" <=> 0
return 1 <=> [1, 2, 3]
Ignoring object property names and going by the order of the property definition seems like asking for trouble, too.
There may be easy logical answers to the above given PHP's existing type juggling, but they should be called out explicitly in both the RFC and in any subsequent documentation.
The behaviour would be the same as the current <, <=, ==, >= and > operators. If > currently returns TRUE, then it is 1, if == currently returns TRUE, then it is 0, and if < currently returns TRUE, then it is -1. Despite all the ridiculousness of our existing comparison rules, apparently <, == and > returning TRUE
are mutually exclusive, thank goodness.
I don’t really want to cover this behaviour in the RFC, because explaining it in full is a considerable effort and the rules it uses are not new, they are the ones PHP already uses. The behaviour for arrays is perhaps a little odd, but that is our existing behaviour, and I’d rather not introduce inconsistency by making <=> use different rules to the other operators.
I agree, however, that documentation for this feature should mention the behaviour, possibly just linking to our existing documentation on type juggling.
Thanks.
--
Andrea Faulds
http://ajf.me/
Hi Larry,
This looks potentially quite useful, especially for multi-stage comparisons as you note. Mainly it would mean I don't have to remember which direction is positive or negative, as I can never get that right without looking it up. :-)
Glad you like it. I, too, sometimes have trouble remembering what direction it goes in.The examples say nothing about mixing types, though. Eg, what would these return:
return 0 <=> "0"
return "" <=> 0
return 1 <=> [1, 2, 3]
Ignoring object property names and going by the order of the property definition seems like asking for trouble, too.
There may be easy logical answers to the above given PHP's existing type juggling, but they should be called out explicitly in both the RFC and in any subsequent documentation.
The behaviour would be the same as the current <, <=, ==, >= and > operators. If > currently returns TRUE, then it is 1, if == currently returns TRUE, then it is 0, and if < currently returns TRUE, then it is -1. Despite all the ridiculousness of our existing comparison rules, apparently <, == and > returningTRUE
are mutually exclusive, thank goodness.I don’t really want to cover this behaviour in the RFC, because explaining it in full is a considerable effort and the rules it uses are not new, they are the ones PHP already uses. The behaviour for arrays is perhaps a little odd, but that is our existing behaviour, and I’d rather not introduce inconsistency by making <=> use different rules to the other operators.
I agree, however, that documentation for this feature should mention the behaviour, possibly just linking to our existing documentation on type juggling.
Thanks.
--
Andrea Faulds
http://ajf.me/
Assuming it's accurate and I'm understanding you correctly, I think the
following would be a sufficient statement for the RFC:
The behavior of this operator with mixed types is such that the
following two snippets produce the exact same result in all cases:
return $a <=> $b;
if ($a > $b) {
return -1;
}
elseif ($a < $b) {
return 1;
}
else {
return 0;
}
Or maybe that's implicit in the existing link, I'm not sure. (Now that
I read it over again.) Basically, in order to understand the more
esoteric type juggling that may occur you'd need to mentally expand it
to its "uncompressed form", for which the rules are already defined (if
possibly quirky in some cases).
--Larry Garfield
Hi again,
Assuming it's accurate and I'm understanding you correctly, I think the following would be a sufficient statement for the RFC:
The behavior of this operator with mixed types is such that the following two snippets produce the exact same result in all cases:
return $a <=> $b;
if ($a > $b) {
return -1;
}
elseif ($a < $b) {
return 1;
}
else {
return 0;
}Or maybe that's implicit in the existing link, I'm not sure. (Now that I read it over again.) Basically, in order to understand the more esoteric type juggling that may occur you'd need to mentally expand it to its "uncompressed form", for which the rules are already defined (if possibly quirky in some cases).
Yes, that’s correct. Although it would be more accurate to say that ($a < $b) is just ($a <=> $b === -1), ($a > $b) is just ($a <=> $b === 1) and similar things for >= and <=, as that’s how the comparison operators work internally (with the exception of == which also has a fast case).
I think I’ll add something along those lines to the RFC.
Thanks.
Andrea Faulds
http://ajf.me/
Hi all,
On Fri, Jan 23, 2015 at 7:48 AM, Larry Garfield larry@garfieldtech.com
wrote:
The examples say nothing about mixing types, though. Eg, what would these
return:return 0 <=> "0"
return "" <=> 0
return 1 <=> [1, 2, 3]
Ignoring object property names and going by the order of the property
definition seems like asking for trouble, too.
It should be the same as '===', IMO.
Only the same type should return 0.
Object has the same id should return 0.
Arrays would be matter of discussion.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Yasuo,
Hi all,
On Fri, Jan 23, 2015 at 7:48 AM, Larry Garfield larry@garfieldtech.com
wrote:The examples say nothing about mixing types, though. Eg, what would these
return:return 0 <=> "0"
return "" <=> 0
return 1 <=> [1, 2, 3]
Ignoring object property names and going by the order of the property
definition seems like asking for trouble, too.It should be the same as '===', IMO.
Only the same type should return 0.
Object has the same id should return 0.
Arrays would be matter of discussion.
Having it be the same as === would be inconsistent with our existing sorting and comparison behaviour, so I don’t think it should be changed. If we made it strict like that, we’d also have to define a strict < and > as well, otherwise we have a problem, because in some cases ($x !== $y && !($x < $y) && !($x > $y)) is TRUE.
Thanks.
--
Andrea Faulds
http://ajf.me/
Hi Andrea,
Having it be the same as === would be inconsistent with our existing
sorting and comparison behaviour, so I don’t think it should be changed. If
we made it strict like that, we’d also have to define a strict < and > as
well, otherwise we have a problem, because in some cases ($x !== $y && !($x
< $y) && !($x > $y)) is TRUE.
Ok. Now I understand. Since we don't/can't define strictly typed
less/greater than operator,
it makes sense. It can be handles
if (get_type($a) != get_type($b)) { ... treat it as exception/error etc }
return $a <=> $b;
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Ok. Now I understand. Since we don't/can't define strictly typed
less/greater than operator,
it makes sense. It can be handles
I always realize silly mistake after I sent mails :(
It can be handled as
if (get_type($a) != get_type($b)) { ... treat it as exception/error etc }
return $a <=> $b;
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Having it be the same as === would be inconsistent with our existing sorting and comparison behaviour, so I don’t think it should be changed. If we made it strict like that, we’d also have to define a strict < and > as well, otherwise we have a problem, because in some cases ($x !== $y && !($x < $y) && !($x > $y)) is TRUE.
I think that you mentioned that you might come up with another RFC if <=> is
successful - that would be for a <==> operator.
You might want to mention that ... but it is more complicated if the operands
are of different types - what does it return in that case ? FALSE
? But the same
as <=> if the types are the same ?
--
Alain Williams
Linux/GNU Consultant - Mail systems, Web sites, Networking, Programmer, IT Lecturer.
+44 (0) 787 668 0256 http://www.phcomp.co.uk/
Parliament Hill Computers Ltd. Registration Information: http://www.phcomp.co.uk/contact.php
#include <std_disclaimer.h
Hi Alain,
Having it be the same as === would be inconsistent with our existing sorting and comparison behaviour, so I don’t think it should be changed. If we made it strict like that, we’d also have to define a strict < and > as well, otherwise we have a problem, because in some cases ($x !== $y && !($x < $y) && !($x > $y)) is TRUE.
I think that you mentioned that you might come up with another RFC if <=> is
successful - that would be for a <==> operator.You might want to mention that ... but it is more complicated if the operands
are of different types - what does it return in that case ?FALSE
? But the same
as <=> if the types are the same ?
The RFC did originally say that, Davey had thought of it. I'm not too keen on the idea and have removed that bit: I don't really think you can do any reasonable "strict" ordering. An error on unmatching types is a royal pain, and I know this because I've had to deal with Game Maker Language which did this. Sorting by type is fairly unintuitive.
I think that if people want strict ordering, it's trivial to implement the particular scheme they want using <=>, casts, type checks, or strcmp()
.
Thanks!
--
Andrea Faulds
http://ajf.me/
Hi all,
Having it be the same as === would be inconsistent with our existing
sorting and comparison behaviour, so I don’t think it should be changed. If
we made it strict like that, we’d also have to define a strict < and > as
well, otherwise we have a problem, because in some cases ($x !== $y && !($x
< $y) && !($x > $y)) is TRUE.I think that you mentioned that you might come up with another RFC if
<=> is
successful - that would be for a <==> operator.You might want to mention that ... but it is more complicated if the
operands
are of different types - what does it return in that case ?FALSE
? But
the same
as <=> if the types are the same ?The RFC did originally say that, Davey had thought of it. I'm not too keen
on the idea and have removed that bit: I don't really think you can do any
reasonable "strict" ordering. An error on unmatching types is a royal pain,
and I know this because I've had to deal with Game Maker Language which did
this. Sorting by type is fairly unintuitive.I think that if people want strict ordering, it's trivial to implement the
particular scheme they want using <=>, casts, type checks, orstrcmp()
.
The only reasonable behavior for <==>, <==, >== would be raising
error/exception if type differs.
E_RECOVERABLE_ERROR
may be used.
If anyone write RFC for these operators, I'll vote +1.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi!
The only reasonable behavior for <==>, <==, >== would be raising
error/exception if type differs.
E_RECOVERABLE_ERROR
may be used.
Comparison operators raising exceptions doesn't sound like a very nice
thing to work with.
--
Stas Malyshev
smalyshev@gmail.com
Hi Stas,
The only reasonable behavior for <==>, <==, >== would be raising
error/exception if type differs.
E_RECOVERABLE_ERROR
may be used.Comparison operators raising exceptions doesn't sound like a very nice
thing to work with.
I agree. As I’ve already mentioned, I have used (sometimes still do use) the relatively obscure Game Maker Language, which made this mistake. 1 == “1” is an error, “1” < 1 is an error, and so on. It is incredibly impractical, especially since you’ll sometimes get the “wrong” type when errors happen, just like how in PHP a function might return FALSE
or NULL
if it’s given the wrong arguments. Compare that value, and bam, your game just crashed! I really don’t think we should make the mistake of copying GML here.
Thanks.
--
Andrea Faulds
http://ajf.me/
Hi Stas,
On Sat, Jan 24, 2015 at 8:42 AM, Stanislav Malyshev smalyshev@gmail.com
wrote:
The only reasonable behavior for <==>, <==, >== would be raising
error/exception if type differs.
E_RECOVERABLE_ERROR
may be used.Comparison operators raising exceptions doesn't sound like a very nice
thing to work with.
I meant if it's ever implemented.
DbC would do the job to prevent/detect illegal comparison and it's much
better
than catching errors in comparison. IMHO.
Type hint is useful for preventing/detecting illegal comparisons also.
There are many
cases that types are better to be checked always. However, there are many
cases that
type checks are better to be omitted for production code also. DbC can be
use in this case
for faster execution while asserting types during development.
Anyway, it's off topic.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi!
The operator is also less clear ... if I see "$a <=> $b" and do not happen
to be familiar with another language implementing this operator, I won't
That can be said about every syntax construct - if you never seen it
before, you'd have to learn. <=> is used in Perl, Ruby and Groovy - so
it's not exactly unknown thing we've just invented, and if you've seen
it once, you'd never forget what it means. It has the form that
perfectly describes its function, so there's no real confusion here.
have any idea what it does (the closest thing <=> could be is the
equivalence operator from logic, and that's not the case here). On the
other hand something like compare($a, $b) is pretty obvious. If there is
concern about clashing with user-defined functions, lets namespace it.
So instead of $a <=> $b, you'd get something like
\PHP\compare_function($a, $b) or maybe even
\PHP\Ordering\compare_function? I don't think most people would prefer
the latter. Operators exist for a reason, and comparison is a frequent
enough case to make operator - especially one that has a long tradition
in other scripting languages - warranted.
Stas Malyshev
smalyshev@gmail.com
Hi Andrea,
This is a reboot of Davey Shafik’s RFC (with permission). After recent
discussions about sort functions, I was inspired to bring this back up, as
I think it would be a useful feature.The RFC is here: https://wiki.php.net/rfc/combined-comparison-operator
Ruby has it. Semantics is the same.
http://ruby-doc.org/core-1.9.3/Comparable.html
PERL has it. Semantics is the same.
http://perldoc.perl.org/perlop.html#Operator-Precedence-and-Associativity
Python has similar "<>", but it only compares equality. (the same as !=,
!==)
[yohgaki@dev github-php-src]$ python
Python 2.7.8 (default, Nov 10 2014, 08:19:18)
[GCC 4.9.2 20141101 (Red Hat 4.9.2-1)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
1 <> 1
False
1 <> 0
True
1 <> 1
False
1 <> 2
True
MySQL has it. Different differs. It's for NULL
comparison.
http://dev.mysql.com/doc/refman/5.6/en/comparison-operators.html#operator_equal-to
There is no reason not to have it, it seems.
I suggest to add Ruby/PERL operator link to the RFC.
I would like to name it other than T_SPACESHIP.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hey Yasuo,
Ruby has it. Semantics is the same.
http://ruby-doc.org/core-1.9.3/Comparable.htmlPERL has it. Semantics is the same.
http://perldoc.perl.org/perlop.html#Operator-Precedence-and-Associativity
Yep, and I mentioned as much. It’s also in Groovy, but it’s not as well-known a language.
Python has similar "<>", but it only compares equality. (the same as !=,
!==)
Actually, PHP also has <> (as do one or two other languages). I think it’s a relic of BASIC, which had = for equality and <> for inequality. I don’t think it’s used terribly much by the user base.
MySQL has it. Different differs. It's for
NULL
comparison.
http://dev.mysql.com/doc/refman/5.6/en/comparison-operators.html#operator_equal-to
Yeah, I’m aware of that. I think this is the one case that might cause confusion, since MySQL and PHP are used together so often. The manual could have a note on it, I suppose.
There is no reason not to have it, it seems.
I suggest to add Ruby/PERL operator link to the RFC.
Good idea, I’ve done that now (I chose a slightly better link for Perl). I’ve also linked to the Wikipedia article about the operator.
I would like to name it other than T_SPACESHIP.
There’s a case for that possibly… I don’t think the fancy name hurts much. The syntax error output includes the token name, and it has the same name in some other languages. It wouldn’t be like Paamayim Nekudotayim, which is a name PHP and only PHP has ever used.
Thanks.
Andrea Faulds
http://ajf.me/