On 4.6.2025 16:54:05, Bob Weinand wrote:
On 2.6.2025 18:27:51, Gina P. Banyard wrote:
Hello internals,
This is the second RFC out of a set of type system related RFCs I
want to propose for PHP 8.5.
The objective is to fix a weird quirk of PHP's type system, where
void lives in its own type hierarchy.
This is visible mainly in that a lack of return type is not
isomorphic to a function that has a return type of mixed.
Let me know what you think about it.
RFC: https://wiki.php.net/rfc/void-as-null
Best regards,
Gina P. Banyard
I have to agree with other posters here that the distinction between
null and void is an useful one.
In particular I'd consider the null returned by void to be incidental
rather than intentional. I consider the return value of void functions
"some arbitrary value". It just happens to be null.
Like every function has to return something. But returning null is not
an intrinsic property of a void function. It's an extrinsic one. You
observe void functions to generally return null. But that null in
itself is meaningless.
So, my counter-proposal would be allowing covariance with void and
allowing everything, including non-nullable types as child type of
void functions.
I.e. effectively giving void and never the same semantics, except that
never also indicates that it never returns.
Additionally I'd be in favour of disallowing (e.g. E_WARNING)
consuming the return value of _direct_ calls to void functions (with
the exception of standalone direct calls in short closures, because
consuming that value is intrinsic rather than necessarily
intentional). (Disallowing indirect calls would be detrimental for
usage as callback.)
Bob
Clarification: *opposite* semantics to never (which is the bottom type).
Void would be effectively the top type (only inferior to untyped).
So, it allows child classes to then return a meaningful value when the
interface was just "void" (= no significant return type). As an example,
when the interface says "set($val): void", the child class can specify
"set($val): mixed" and return the old stored value.
Basically, an interface can now say without further clarification "I
have no real return value" = "void", rather than having to say "mixed"
and then explaining "this is not really mixed, but whatever you want".
(I have seen interface method return values being "upgraded" from void
to mixed (or just untyped) in the past, just so that a specific child
class can now return a meaningful value.)
Bob