On 8 April 2022 18:34:52 BST, Craig Francis <cr...@craigfrancis.co.uk> wrote: >I've written a new draft RFC to address the NULL coercion problems: > >https://wiki.php.net/rfc/null_coercion_consistency
I'm sympathetic to the general problem you're trying to solve, but I'm not convinced by the argument that this is about consistency, because user defined functions have been consistently rejecting null for non-nullable parameters since PHP 7.0, and even before that for arrays and objects. Consistency is a good argument for small changes that eliminate unusual edge cases, but I think far-reaching changes should be able to stand on their own merits - regardless of whether it's consistent, do we want the language to work this way? To me, the main defence of type coercion is that PHP operates in a world full of strings - URLs are strings, HTTP requests are strings, and a lot of API responses are strings - so making it easy to work with strings like '42' as numbers makes a lot of sense. It's not clear to me that this extends to null. I think a large part of the problem here is that null can mean many different things in different contexts - "unknown", "not provided", "invalid input", "default", "not applicable", etc. These differences are subtle, but lead to different expectations of behaviour: - Treat null as a specific case with its own meaning, distinct from any other valid value. This is what explicitly nullable parameters and union types allow. - Treat null the same as any other out of range value, and raise an error. This is what happens in user-defined functions in PHP, and in built-in functions expecting non-scalar arguments. Compare also out of range actions like division by zero. - Treat null as a special state that propagates through expressions, because any operation with an unknown input has an unknown output. This is the approach to null taken by SQL, and by IEEE floating point with NaN. It is also the basis of the ?-> operator, and of things like Optional.map in Swift. - Treat null as a generic default value which can be filled in implicitly based on requirements. This is the interpretation currently taken by internal functions for scalar arguments, and what you are proposing to make standard. It is also, as you point out, the way PHP treats null in some other contexts, such as many operators. Interestingly, one of your examples mentions filter_input, which takes the "propagate" approach, and htmlspecialchars, which doesn't. It would often be more useful to retain the information that a value is null than to have it silently converted to an empty string as a side-effect of some other operation. Perhaps it would be useful to have some function-call equivalent of the ?-> operator. I'm not sure what this would look like for normal function calls, but it would be easy to add if we had a pipe operator, e.g.: If this was equivalent to htmlspecialchars($foo) $foo |> htmlspecialchars(...) Then this could be equivalent to ($foo === null ? null : htmlspecialchars($foo)) $foo ?|> htmlspecialchars(...) I'm not set against this RFC, but I'm not quite convinced by the case it makes, and think there may still be other options to explore. Regards, -- Rowan Tommins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php