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

Reply via email to