Re: [Discussion] Stricter implicit boolean coercions
| From: | Andreas Leathley | Date: | Mon, 23 May 2022 19:39:50 +0000 |
| Subject: | Re: [Discussion] Stricter implicit boolean coercions | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-117776@lists.php.net to get a copy of this message | ||
On 23.05.22 20:58, Juliette Reinders Folmer wrote:
This RFC worries me as, in my opinion, it makes PHP's behaviour more surprising and inconsistent, not less. It also raises the cognitive complexity for developers by yet another level. 1. It introduces a new interpretation of boolean type coercion, which is only applied against type declarations. 2. This new interpretation is not consistent with "normal" boolean type coercion, not consistent with strict types (no coercion) and also not consistent with what is considered a valid boolean value by the Filter extension.I am not sure what you mean by "normal" boolean type coercion and how it would be inconsistent with those. The RFC does not change the behavior of boolean type coercions, it just points out possibly surprising coercions. The filter extension has its very own interpretation of how to validate a boolean which is completely incompatible with how PHP does implicit type coercions already. Yet people using the filter extension are not affected by this RFC at all, they have already chosen their way to convert a value to boolean. But comparing the filter extension with the implicit type conversion does show how dangerous it can be to for example switch from FILTER_VALIDATE_BOOLEAN (with FILTER_NULL_ON_FAILURE) to the implicit boolean conversions from PHP: with the filter extension "false", "off" and "no" are converted to false, while all these values are silently converted to true by implicit boolean conversion by PHP. People switching from the filter extension to the built-in types of PHP have another way of shooting themselves in the foot, and it is easy to miss the change in behavior.
While I agree that the current behaviour of PHP can hide bugs, I fear that even more bugs will be introduced when PHP contains yet a third form of coercion to boolean and the type coercion used is dependent on the context.Assuming from the rest of your response, I am assuming you mean "truthiness" comparisons, like in if statements and other expressions. Those are already different from coercions to typed booleans and have different semantics. In an if statement you can check for truthiness with any type, while a typed boolean only accepts scalar values. I am seeing an advantage of further separating those use cases, as a misconception seems to exist that a check for truthiness is just a conversion to boolean. Having clearer semantics would actually lower cognitive complexity from my perspective - knowing that only 7 values are considered sensible for a typed boolean and getting a notice for any other values makes it a lot clearer how it behaves and when I as a developer will get warned.
I fear this will only lead to more bugs, not less (because people new to PHP will learn the "type declaration" based boolean coercion rules and assume they apply everywhere).But they would actually apply anywhere, as far as I know: My suggested allowed values for typed booleans can be used in if statements and lead to the exact same behavior.
I also fear that for code bases which do not (yet) use scalar type declarations, this will be one more argument not to introduce scalar type declarations (while they should).My suggestion is far less impactful for "legacy" codebases compared to the other scalar type checking - an "int" parameter only accepting valid numbers and leading to a TypeError otherwise is a much bigger hurdle from my perspective than introducing a deprecation notice for a suspect boolean type coercion. I cannot really believe that "failed" not being auto-coerced to true will be the straw that breaks the camels back in legacy codebases. And again: It is just a deprecation notice, I even amended the RFC to say that this being elevated to a TypeError will have to be decided after the impact of the deprecation notices become clear, not now. My goal is not necessarily to be as strict as possible but rather point out to developers where something might be going wrong.
I'd say that for this RFC to be acceptable it would need to apply to all implicit type coercions to boolean. However, the BC-break that would cause and the fall-out of this for non-greenfields codebases is just too huge, which, to me, makes this RFC a very strong no-no.I will amend the RFC to show how typed booleans already have their own type coercions that are not the same as the truthiness checks in if or similar expressions - thanks for pointing that out and showing that there is some confusion there that might benefit from a clearer explanation. Changing how truthiness is evaluated in PHP makes no sense to me though, and I don't think such a drastic step is necessary to get a lot of benefits. If you have further feedback, I would be happy to hear it. So far I have not gotten much feedback, and most of it was going towards being positive, so being able to get to know the other perspective would help to address it in the RFC and improve it overall.