Re: [RFC] Strict operators directive
| From: | Marc | Date: | Wed, 10 Jul 2019 22:24:27 +0000 |
| Subject: | Re: [RFC] Strict operators directive | ||
| References: | 1 2 3 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-106208@lists.php.net to get a copy of this message | ||
Hi,
On 10.07.19 23:37, Arnold Daniels wrote:
I would argue that two operands will not be the same if they are of different types (except for int/float). Means 0 == "" and 0 == "0" will both be false but 0 == 0 and 0 == 0.0 will be true. Note: In my opinion int/float check should also make sure that there is no data loss on comparing a very bit integer to a float. In this case they should not be equal.* I also find it somewhat odd that you can't write something like "$obj != null" anymore, only "$obj !== null".To check against null, it's better to use !==. For objects (and resources) using!= nullis ok, but for other types, it's currently not. For example;[] == nullgives true.
I thing this goes hand in hand with the empty check like empty("0") is true but empty("00") is false. I couldn't find how/if this will change with this RFC.* I think the "solution" to the last three points is a) only support numbers in relational operators (<,<=,>,>=,<=>) and throw TypeErrors otherwise (maybe modulo provisions for object overloading) and b) allow comparing any types in == and !=, without throwing a TypeError. The question "Are 42 and 'foobar' equal?" has a pretty clear answer: "No they aren't", so there is no need to make this a TypeError (while the question "Is 42 larger than 'foobar'?" has no good answer.) I believe doing something like this would roughly match how Python 3 works. (Edit: I see now that this is mentioned in the FAQ, but I think it would be good to reconsider this. It would solve most of my problems with this proposal.)Besides the argument in the FAQ, having the == and != return do a type check, means there are a lot more cases where the behavior changes rather than that a TypeError is thrown. Currently"foobar" == 0returns true, but this would make it return false. So would1 == true,"0" == 0and"0" == false. To reduce the cases where the behavior changes to a minimum, it's better to throw TypeErrors for == and !=.
I do agree here. Even if working with binary strings isn't most common in PHP web development I actually use these for bitsets. But I have a note here that bit shifting currently does not work with binary strings (tries to cast binary string to integer) and even if it would shift the binary string the >> is designed to keep the first bit as a positive/negative flag which of course does not make sense for binary strings. In my opinion the bit shifting operators should accept and work well with binary strings. I don't see a reason why it's performing a type cast here.* String increment seems like a pretty niche use case, and I believe that many people find the overflow behavior quite surprising. I think it may be better to forbid string increment under strict_operators.Ok* A similar argument can be made for the use of &, | and ^ on strings. While I have some personal fondness for these, in practical terms these are rarely used and may be indicative of a bug. I think both for string increment and string and/or/xor it may be better to expose these as functions so their use is more explicit.These operators make it very easy to work with binary data as strings in PHP. In other languages you have to work with byte arrays, which is a major pain. They're also very intuitive;"wow" & "xul"is the same as `chr(ord('w') & ord('x')) . chr(ord('o') & ord('u')). chr(ord('w') & ord('l'))`. I think these should stay.
MarcRegards, NikitaArnold