On Sat, Aug 14, 2021, 14:48 G. P. B. <george.bany...@gmail.com> wrote:
> On Sat, 14 Aug 2021 at 10:55, Deleu <deleu...@gmail.com> wrote: > >> Hi Jordan, >> >> Does it make sense to explain in the RFC the difference between never and >> mixed in this context? The RFC vaguely mentions that never can never be >> used directly, but if it's limited to abstract class and interfaces, isn't >> that already impossible to use directly? Or does it mean that the type >> would "be allowed" on any function, but because of its intrinsic behavior >> it would always fail if used in non-abstract methods? >> >> Another clarification I'd be interested is about dropping the type >> declaration entirely (e.g. https://3v4l.org/a4bfs), because of covariance >> (or contravariance, I never know), sub classes can completely drop type >> declaration entirely. Will never not allow this? Why? Why not? If it does >> allow this, does it really differ from not having any type declaration on >> the abstract function? >> >> My knowledge in this area is practically null so if I'm asking stupid >> questions that are easily explained by some blog post I'd he happy to read >> it. >> > > never and mixed are on opposite sides of the type hierarchy. > mixed is the top type, meaning it's the supertype of any other types, and > any other type is a subtype of mixed (excluding void which is not really a > "type" if you look at it, from my understanding, in a type theory way). > never on the other side is the bottom type, meaning it's the subtype of > any other type, and any other type is a supertype of never. > Finally a lack of type declaration is treated as mixed. > > Liskov's substitutions rules dictate that return types are co-variant i.e. > more specific, and argument types are contra-variant i.e. more general. > This is why any return type can be replaced by never and any argument type > can have it's type dropped/changed to mixed. > As such replacing never by mixed in an argument is totally possible as > mixed is a wider type than never. > This was incredibly useful, thank you very much. The essence that I took away is that if I declare mixed on my interface, then making it more specific (co-variant) is impossible e.g. ``` interface A { public function t(mixed $t); } interface B extends A { public function t(A $t); } ``` This is where never, being a bottom type, shines. I guess the bike shed of this one is the awkwardness of declaring an input as `never` but I'd imagine we'll either get used to it or use a possible future type alias to do `type something = never`. I guess the best aliases would be any or something, but given the interesting use case I don't think it's worth to reject this RFC solely based on how awkward `never $var` is. TL;DR thank you and I like it. >