Re: [RFC] Never For Argument Types
| From: | Claude Pache | Date: | Sat, 14 Aug 2021 17:12:56 +0000 |
| Subject: | Re: [RFC] Never For Argument Types | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-115729@lists.php.net to get a copy of this message | ||
>
> On Fri, 13 Aug 2021 at 19:27, Jordan LeDoux <jordan.ledoux@gmail.com> wrote:
>
>> Hey internals,
>>
>> I've been working on the draft for my operator overloading RFC, and in
>> doing so I encountered a separate change that I would like to see.
>>
>> That is, the use of
never as an argument type for
>> interfaces. Since
>> arguments in PHP are contravariant to preserve Liskov substitution,
>> never
>> as the bottom type should indicate that implementing classes can require
>> any type combination they want. This is in fact consistent with type theory
>> and set theory, and is how the bottom type is treated in several other
>> languages.
>>
>> In this case, the bottom type would be used to indicate covariant parameter
>> polymorphism while not conflicting with LSP.
>>
>> This would provide a sort of minimal form of generics to PHP without the
>> issues that actual generics present from an implementation perspective. It
>> would not, however, restrict or hinder any future RFC for generics.
>>
>> This is at the first draft stage, and I currently have the RFC on a github
>> repo to allow for easy contribution and collaboration.
>>
>> Any feedback is greatly appreciated.
>>
>> https://github.com/JordanRL/never-argument-type
>>
>> Jordan
>>
> Le 14 août 2021 à 18:19, Matthew Brown <matthewmatthew@gmail.com> a écrit :
>
> Hey!
>
> Using the "never" type to require that downstream libs specify a type does
> not make intuitive sense to me, because the same is not true the other way
> (covariantly) for return types.
>
> The existence of a "never" type on an overriding method does not require
> that upstream libs specify a return type — this is perfectly valid:
>
> class A {
> public function foo() {}
> }
> class AChild extends A {
> public function foo():never { exit; }
> }
>
> Best wishes,
>
> Matt
Indeed, I was going to write something similar. Concretely, I assume that one would want to update
the ArrayAccess internal interface as follows:
```php
interface ArrayAccess {
public function offsetGet(never $x): mixed;
// ...
}
```
If users of that interface would suddenly be *required* to specify a parameter type, whereas
previously they were *forbidden* to specify one, except a meaningless mixed... it would
be not nice and useless.
Moreover, note that mixed was only introduced very recently, in 8.0: so that, it would
be impossible to implement ArrayAccess on code that work both in 7.x and a future
version with the updated interface. Not only would it be not nice, but it would be positively
harmful.
—Claude