On 02/06/2025 17:27, Gina P. Banyard wrote:
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.


I think if "void" was added now, it would be an attribute, rather than a type. It is in effect the exact opposite of #[\NoDiscard], and distinguishes between these two cases:

interface Foo {
   public function getSomething(): ?Something;
}

class MyFoo implements Foo {
   public function getSomething(): null {
       // My result is always null, but still meaningful to consumers of the Foo interface
       return null;
   }

   #[\DiscardReturn]
   public function doSomething(): null {
        // I have no meaningful information to return; any assignment of my implicit value is a mistake
   }
}

I agree the type hierarchy you describe is weird, but rather than throwing away the functionality completely, I wonder if we can make it more consistent:

- Make "no return type declared" and "mixed" equivalent
- Make "void" a sub-type of "null", and therefore a sub-type of "mixed"

If I've got that right, this would then be legal:

class A{ public function foo() {} } class B extends A{ public function foo(): 
mixed{} }
class C extends B{ public function foo(): null{} }
class D extends C{ public function foo(): void{} }
class E extends D{ public function foo(): never {} }

That seems reasonable enough; I may have missed something important, though.

Regards,

--
Rowan Tommins
[IMSoP]

Reply via email to