Hi Craig,

> No, there is an inconsistency which leads to a backwards compatibility
issue, and I'm trying to fix it.

Which inconsistency exactly do you have in mind?

The discussion is about passing arguments to functions. We are not
discussing type juggling or type casting. To clarify the whole thing let's
list out the key points:

- PHP has a concept of scalar types consisting of these four types: string,
int, float, bool
- PHP has type juggling that converts the value to the type required by the
context in which it is used. The behaviour is defined for scalar types, but
often undefined for other types (see juggling to array)
- PHP lets users cast values to a specified type. There are 7 (+1)
available casts in PHP (disregarding aliases). Casting to scalar types from
scalar types is defined. Casting to scalar from other types is partially
defined and causes undefined behaviour in some cases. Warnings are
generated in certain situations (e.g. array to string) and fatal errors
when the cast cannot be performed at all.
- PHP has a special type called NULL with a single value NULL. It's not a
scalar and it's not a stand-alone type. Casting to NULL is not possible.
For all intents and purposes, NULL value represents a variable with no
value. For this reason, converting to other types generally does not cause
any notices, warnings or errors. However, using NULL might generate
warnings or errors depending on an operation. e.g. `null[0]`,
`null->scalar` or `[...null]`
- PHP has a concept of strict typing. It applies only to scalar parameters.
By default, PHP will coerce values of the wrong type into the expected
scalar type declaration if possible. NULL being a non-scalar value doesn't
coerce in non-strict mode. Neither does array, object or resource. See
https://3v4l.org/WZdQC

The only inconsistency is that PHP's internal functions silently accepted
NULL values for non-nullable parameters. This will be addressed in PHP 9.0.

Changing the signatures of some functions might be reasonable but, as few
others have said, it's not the solution we want to see because it feels
like a hack. As I have also pointed out off-list, in many cases making the
parameter type nullable would not make any sense as passing null to certain
functions is a clear bug. It would also have an impact on strict typing!

We could also reclassify NULL as a scalar type but that would be a
fundamental language change. It would likely be a bigger BC change than
fixing the current inconsistency.

By the way, your statement that "Coercion works for string/int/float/bool,
*and* NULL." is invalid. Coercion is defined only for scalar types as I
have explained above. Type juggling for most types from NULL is defined,
but that is not what we are discussing.

Regards,
Kamil

Reply via email to