Re: [RFC] [Discussion] Never parameters

From: Date: Mon, 10 Mar 2025 22:11:25 +0000
Subject: Re: [RFC] [Discussion] Never parameters
References: 1  Groups: php.internals 
Request: Send a blank email to [email protected] to get a copy of this message
Hi Daniel,

> On Mar 11, 2025, at 08:05, Daniel Scherzer <[email protected]> wrote:
> 
> Hi internals,
> 
> I'd like to start discussion on a new RFC about allowing never for parameter
> types when declaring a method.
> 
> * RFC: https://wiki.php.net/rfc/never-parameters-v2
> * Implementation: https://github.com/php/php-src/pull/18016
> 
> -Daniel


The RFC says that:

> never can be used as a parameter type, subject to the following restrictions
> 
> * it cannot be used in the declaration of any method that has an implementation. Methods with
> never can never (pun intended) be called, because there are no values that satisfy the type
> constraint. Instead of delaying the error until runtime when the user attempts to call the method,
> just require that the method not have a body.


I would point out that never can be conceptually represented as a caseless enum. Right
now, code like this is valid (as in, does not produce errors, though in practice, it's also not
callable):

> enum Never {}
> function foo(Never $never) { echo "wat"; }
> function bar(Never $never) { foo($never); }

If we're going to deny the use of never as a parameter to a function with a body
(even an empty body), perhaps we should also consider the caseless enum case. For the sake of
consistency, we might want to deny use of caseless enums as function parameters. Alternatively, we
might want to explicitly allow that use case to allow for a "I know I'm going to have
cases here, but I don't know what they will be, but I'm still going to write some
functional code around this first and would very much like my code to compile even though I
haven't actually added any cases yet." scenario. Which I have definitely done before.
Either way, it's an inconsistency worth clarifying.

This is a bit future-gazing, but, when considered in the context of generics, it's normal and
useful to have class members and bodied functions with (generically) never types. You might see
this, for example, with a Result<Success, Failure> type, where Failure == Never. We would want
to allow those use-cases, and disallowing it for non-generic functions would be an inconsistency.

-John


Thread (33 messages)