rfc:true-type
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
rfc:true-type [2022/04/08 16:18] – Add compile time redundancy checks girgias | rfc:true-type [2022/05/29 14:38] – Change status girgias | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== PHP RFC: Add true type ====== | ====== PHP RFC: Add true type ====== | ||
- | * Version: 0.1 | + | * Version: 0.2 |
* Date: 2022-04-7 | * Date: 2022-04-7 | ||
* Author: George Peter Banyard, < | * Author: George Peter Banyard, < | ||
- | * Status: | + | * Status: |
* Target Version: PHP 8.2 | * Target Version: PHP 8.2 | ||
- | * Implementation: | + | * Implementation: |
* First Published at: [[http:// | * First Published at: [[http:// | ||
===== Introduction ===== | ===== Introduction ===== | ||
- | PHP now has support for [[rfc: | + | PHP now has support for [[rfc: |
However, '' | However, '' | ||
- | The motivations are the same to previous RFC targeting the type system: | + | The motivation in the [[rfc: |
- | | + | < |
- | * Providing | + | While we nowadays encourage the use of null over false as an error or absence return value, for historical reasons many internal functions continue to use false instead. As shown in the statistics section, the vast majority of union return types for internal functions include false. |
+ | |||
+ | A classical example is the < | ||
+ | |||
+ | While it would be possible to model this less accurately as '' | ||
+ | |||
+ | For this reason, support for the '' | ||
+ | </ | ||
+ | |||
+ | We believe there are now sufficient reasons to include support for the '' | ||
+ | |||
+ | With the introduction of < | ||
+ | a large amount of internal functions which used to return '' | ||
+ | And they now always return '' | ||
+ | Moreover a '' | ||
+ | < | ||
+ | if (function_which_could_fail_before()) { | ||
+ | // Do useful stuff | ||
+ | } else { | ||
+ | | ||
+ | } | ||
+ | </ | ||
+ | Marking these internal functions as having a return type of '' | ||
+ | |||
+ | |||
+ | Another motivation is providing more precise type information | ||
+ | For example a child method which always returns '' | ||
+ | |||
+ | < | ||
+ | class User { | ||
+ | function isAdmin(): bool | ||
+ | } | ||
+ | |||
+ | class Admin extends User | ||
+ | { | ||
+ | function isAdmin(): true | ||
+ | { | ||
+ | return true; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Finally, being able to add a '' | ||
===== Proposal ===== | ===== Proposal ===== | ||
Add support for using '' | Add support for using '' | ||
+ | The '' | ||
<PHP> | <PHP> | ||
Line 43: | Line 86: | ||
< | < | ||
- | A compile time error is also emitted when '' | + | ==== Compile time error for using true|false instead of bool ==== |
+ | |||
+ | A compile time error is also emitted when '' | ||
The following function signature: | The following function signature: | ||
<PHP> | <PHP> | ||
Line 54: | Line 99: | ||
Fatal error: Type contains both true and false, bool should be used instead in %s on line %d | Fatal error: Type contains both true and false, bool should be used instead in %s on line %d | ||
</ | </ | ||
+ | |||
+ | The rationale is that the subtyping relation between '' | ||
+ | As '' | ||
+ | It is possible to make '' | ||
+ | Therefore the conservative approach of banning the usage of '' | ||
==== Examples ==== | ==== Examples ==== | ||
- | There are many examples of functions which only return '' | + | There are many examples of functions which only return '' |
- | Example | + | |
- | And examples | + | Some examples |
+ | many < | ||
+ | |||
+ | An example | ||
[[https:// | [[https:// | ||
[[https:// | [[https:// | ||
Line 82: | Line 135: | ||
Voting started on 2022-03-12 and will end on 2022-03-26. | Voting started on 2022-03-12 and will end on 2022-03-26. | ||
- | <doodle title=" | + | <doodle title=" |
* Yes | * Yes | ||
* No | * No | ||
</ | </ | ||
- | | + | |
+ | |||
+ | |||
+ | ===== Future Scope ===== | ||
+ | |||
+ | The features discussed in the following are **not** part of this proposal. | ||
+ | |||
+ | ==== Literal Types ==== | ||
+ | |||
+ | The '' | ||
+ | |||
+ | <code php> | ||
+ | type ArrayFilterFlags = 0|ARRAY_FILTER_USE_KEY|ARRAY_FILTER_USE_BOTH; | ||
+ | array_filter(array $array, callable $callback, ArrayFilterFlags $flag): array; | ||
+ | </ | ||
+ | |||
+ | A benefit of using a union of literal types instead of an enum, is that it works directly with values of the underlying type, rather than an opaque enum value. As such, it is easier to retrofit without breaking backwards-compatibility. | ||
+ | |||
+ | However, the opinion of the authors is that enums are superior to literal types and the reason to add '' | ||
+ | |||
+ | ==== Allowing usage of true|false ==== | ||
+ | |||
+ | To allow the usage of '' | ||
+ | |||
+ | ==== Type Aliases ==== | ||
+ | |||
+ | As types become increasingly complex, it may be worthwhile to allow reusing type declarations. There are two general ways in which this could work. One is a local alias, such as: | ||
+ | |||
+ | <code php> | ||
+ | use int|float as number; | ||
+ | |||
+ | function foo(number $x) {} | ||
+ | </ | ||
+ | |||
+ | In this case '' | ||
+ | |||
+ | The second possibility is an exported typedef: | ||
+ | |||
+ | <code php> | ||
+ | namespace Foo; | ||
+ | type number = int|float; | ||
+ | |||
+ | // Usable as \Foo\number from elsewhere | ||
+ | </ | ||
===== Implementation ===== | ===== Implementation ===== | ||
- | GitHub pull request: https:// | + | GitHub pull request: https:// |
After the project is implemented, | After the project is implemented, |
rfc/true-type.txt · Last modified: 2022/06/12 10:09 by girgias