To have any information content, a variable (or return value, or parameter) needs to have more than one possible value. If one of those values is TRUE, the most natural alternative value would be FALSE.
But should this really be baked into the language? Should really "try to be smart" here? Isn't it better to aim for completeness and consistency, and provide a "round" developer experience with the least amount of surprise? The same could be asked about other restrictions, e.g. false|null. Ideally we should have a type system with the properties of a mathematical space of some sort. Artificial restrictions would ruin this. It won't be perfect, because the different types are not "symmetric". But we can at least try to make it as consistent as possible. Some use cases I can think of: ## Use case: true[] assoc I like to use true[] for map-like associative arrays. So, $map[$key] = true; For each key, the array either has the value TRUE, or no value at all. No need to store false values. An extended use case might be a (tree = true|tree[]), where each leaf would have the value true. Does this mean we need true for parameters and return types? It will be rare. Especially in the first case of a simple true[], there is no point returning the value in a variable, if we not also allow FALSE for "not found". ## Use case: Generics However, what if the code is written in a generic way? E.g. if PHP gets native generics one day, or some userland generics library based on code generation. For an iterator over true[], the return value for ->current() would be "true|null". (I just tried, it is null and not false, see https://3v4l.org/PvWWl). For a generic method receiving values from the array, the parameter type would be "true". It would be really disappointing if a tool that attempts to give us generics would have to work around arbitrary limitations of the typing system. ## Use case: Variance Imagine a base class or interface method which returns boolean for success / failure. We extend this method, and our implementation is always successful, so we will always return true. We can indicate this in the type hint. This indicates that calling code does not need to check the return value, it can simply assume that it was successful. interface Operation { function run(): bool } interface SafeOperation extends Operation { function run(): true // always successful. } ## Use case: Code generation and reflection tools I would say that for any automated tool, special cases of disallowed types make things more complicated. This could be tools for code generation, parsing, or some kind of "type reflection" with type arithmetics. ## Use case: Legacy code Finally, in some cases it is irrelevant whether the combination of types makes sense or not. We simply want to type-harden legacy code. On Mon, 23 Sep 2019 at 22:15, Benjamin Morel <benjamin.mo...@gmail.com> wrote: > > Hi Nikita, > > Thank you for your work on this, I look forward to being able to use union > types! > > The one thing that bothers me a bit is introducing yet another > inconsistency by supporting false and not true as a type. Sure, I do get > the need for false as a valid type for historical reasons, but at the same > time I thought it would be interesting to see if true was being used as > well in the wild, before closing the door on it. > > Therefore I reviewed all Composer packages with > 1 million downloads (1211 > packages total), and here are the results: > > *31 packages > <https://gist.github.com/BenMorel/56dfff576b1d8a719cd71b14ef614d2e#file-packages-txt> > use at least one @var, @param or @return containing true as a type.* > > - there are many illegitimate use cases, such as @return true > <https://github.com/drupal/core/blob/c447ebb6a89149ef86e0af06bc00fec63027ec0d/modules/views/src/ViewExecutable.php#L719> > , @return bool|true > <https://github.com/php-http/message/blob/144d13ba024d0c597830636907144bc7c23f50dd/src/Authentication/AutoBasicAuth.php#L23>, > @return true|false > <https://github.com/zendframework/zend-form/blob/ff4c9ec32d141e4ac622c2aa40a8c9eb77a40725/src/Annotation/AnnotationBuilder.php#L412>, > or even @return bool|true|false > <https://github.com/slevomat/coding-standard/blob/964a3ff08d7ee924510c3b705f826165adaa97fe/tests/Sniffs/Namespaces/data/fullyQualifiedClassNameInAnnotationNoErrors.php#L41> > - there are, however, quite a few potentially legitimate use cases. Among > others: > > - @return true|WP_Error > <https://github.com/johnpbloch/wordpress-core/blob/4a96ef28019f3f529465eac71c718afea2c88e8b/wp-includes/rest-api/class-wp-rest-request.php#L641> > (*johnpbloch/wordpress-core*) : "True if the JSON data was passed or no > JSON data was provided, WP_Error if invalid JSON was passed." > - @return true|string > <https://github.com/johnpbloch/wordpress-core/blob/bd27b2bc49483b796fdb228f9b0614f9880823ee/wp-includes/ms-load.php#L72> > (*johnpbloch/wordpress-core*) : "Returns true on success, or drop-in file > to include." > - @return string|true > <https://github.com/PHP-DI/PHP-DI/blob/b891248f04c594dae4c07650bc0815d0dc81bacb/src/Compiler/Compiler.php#L317> > (*php/di*) : True if compilable, string explaining why if not > - @return string|true > <https://github.com/zendframework/zend-authentication/blob/86d6553e1cfe5ed2bde53cbea9fd162c6875a9c8/src/Adapter/Ldap.php#L378> > (*zendframework/zend-authentication*) : True if successfull, error message > if not > - @param int|true > <https://github.com/yiisoft/yii2/blob/fdbe45af3a4f923a97b718d8694981e1e195403d/framework/db/Query.php#L1266> > (*yiisoft/yii2*) : "Use 0 to indicate that..., Use a negative number to > indicate that..., Use boolean `true` to indicate that ..." > - @param callable|resource|string|true|null > <https://github.com/symfony/symfony/blob/242f24427d34bd47ef0e3a027a5a4e979d713c6f/src/Symfony/Component/VarDumper/Dumper/AbstractDumper.php#L117> > (*symfony/symfony*) : "A line dumper callable, an opened stream, an output > path or true to return the dump" > > Full list here > <https://gist.github.com/BenMorel/56dfff576b1d8a719cd71b14ef614d2e#file-types-txt> > . > > So although true as a type does not have the same historical background as > false, it does seem that it's being used by enough packages to be worth > considering; what do you think? > > — Benjamin -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php