On Sat, Aug 14, 2021, at 7:48 AM, G. P. B. 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. > > How I personally see never as an argument type is that you require a > mandatory argument but you leave the type constraint up to the > implementation. > > A recent example which bit us in php-src/the PHP documentation is the > interface of ArrayAccess, all of the $offset parameters have a mixed type. > Until recently the ArrayObject/ArrayIterator had incorrect stubs [1] by > indicating that the argument was of type int|string, which practically is > the case as SPL's ArrayAccess handler will throw a TypeError on different > types, however this is done manually within the call and not when the call > is made. > Ideally the $offset parameter would be of type never such that SPL, and > userland, can specify what type of offsets they accept, be that the usual > int|string, only int for list-like objects, only string for dictionary-like > objects, maybe even object|int|string to allow GMP objects for arbitrary > precision. > Whereas every implementer of ArrayAccess is forced to accept mixed for the > $offset and need to manually enforce the type. > > This is the "power" of the never type as an argument type. > > Best regards, > > George P. Banyard > > [1] > https://github.com/php/php-src/pull/7215/files#diff-e330df347cac9e68d2d07a06535c534cd8c2438a1af703cd4245b8ce91ec65afL9-R10
So... if I am following correctly, the idea is to allow `never` to be used in an interface/abstract method only, as a way to indicate "you must specify a type here of some kind; I don't care what, even mixed, but you have to put something". Am I following? I'm not sure on the type theory of it, but it does feel like a hack at first blush. --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php