rfc:pure-intersection-types
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
rfc:pure-intersection-types [2021/05/04 21:21] – Creation girgias | rfc:pure-intersection-types [2021/07/05 12:17] (current) – Mark as implemented girgias | ||
---|---|---|---|
Line 4: | Line 4: | ||
* Date: 2021-03-23 | * Date: 2021-03-23 | ||
* Author: George Peter Banyard, < | * Author: George Peter Banyard, < | ||
- | * Status: | + | * Status: |
* Target Version: PHP 8.1 | * Target Version: PHP 8.1 | ||
* Implementation: | * Implementation: | ||
Line 38: | Line 38: | ||
* Types are available through Reflection. | * Types are available through Reflection. | ||
* The syntax is a lot less boilerplate-y than phpdoc. | * The syntax is a lot less boilerplate-y than phpdoc. | ||
+ | |||
+ | ===== Motivation ===== | ||
+ | |||
+ | It is possible to emulate intersection types by creating a new interface which inherits from multiple ones, one such case is the built in '' | ||
+ | |||
+ | <code php> | ||
+ | interface CountableIterator extends Iterator, Countable {} | ||
+ | </ | ||
+ | This works, but what if we want an iterator that is countable //and// seekable? We need to create another interface: | ||
+ | |||
+ | <code php> | ||
+ | interface SeekableCountableIterator extends CountableIterator, | ||
+ | </ | ||
+ | As such, each new requirement necessitates the creation of various new interfaces taking into account all possible combinations. | ||
+ | |||
+ | Moreover, the class needs to implement the specific interface and cannot rely on just implementing the base interfaces, meaning the introduction of such interfaces need to be propagated to all relevant classes, something which can be error prone. See this non-example: | ||
+ | |||
+ | <code php> | ||
+ | interface A {} | ||
+ | interface B {} | ||
+ | interface AB extends A, B {} | ||
+ | |||
+ | class Test implements A, B {} | ||
+ | |||
+ | function foo(AB $v) { | ||
+ | var_dump($v); | ||
+ | } | ||
+ | |||
+ | foo(new Test()); | ||
+ | </ | ||
+ | Intersection types solve these issues. | ||
===== Proposal ===== | ===== Proposal ===== | ||
Line 61: | Line 92: | ||
==== Supported types ==== | ==== Supported types ==== | ||
- | Only class types (interfaces and class names) are supported by intersection types, this is because | + | Only class types (interfaces and class names) are supported by intersection types. |
+ | |||
+ | The rationale is that for nearly all standard types using them in an intersection type result in a type which can never be satisfied (e.g. '' | ||
+ | |||
+ | Usage of '' | ||
+ | |||
+ | Similarly using '' | ||
+ | |||
+ | Although an intersection with '' | ||
+ | |||
+ | Similarly '' | ||
=== Duplicate and redundant types === | === Duplicate and redundant types === | ||
Line 104: | Line 145: | ||
</ | </ | ||
+ | |||
==== Variance ==== | ==== Variance ==== | ||
- | Intersection types follow | + | Intersection types follow |
* Return types are covariant (child must be subtype). | * Return types are covariant (child must be subtype). | ||
Line 112: | Line 154: | ||
* Property types are invariant (child must be subtype and supertype). | * Property types are invariant (child must be subtype and supertype). | ||
- | The only change is in how intersection types interact with subtyping, with one additional | + | The only change is in how intersection types interact with subtyping, with two additional |
- | * An intersection | + | * '' |
+ | * '' | ||
In the following, some examples of what is allowed and what isn't are given. | In the following, some examples of what is allowed and what isn't are given. | ||
Line 358: | Line 401: | ||
As per the voting RFC a yes/no vote with a 2/3 majority is needed for this proposal to be accepted. | As per the voting RFC a yes/no vote with a 2/3 majority is needed for this proposal to be accepted. | ||
- | ===== Patches and Tests ===== | + | <doodle title="Add pure intersection types to PHP" auth=" |
- | + | * Yes | |
- | Links to any external patches and tests go here. | + | * No |
- | + | </ | |
- | If there is no patch, make it clear who will create a patch, or whether a volunteer to help with implementation is needed. | + | |
- | + | ||
- | Make it clear if the patch is intended to be the final patch, or is just a prototype. | + | |
- | + | ||
- | For changes affecting the core language, you should also provide a patch for the language specification. | + | |
===== Implementation ===== | ===== Implementation ===== | ||
- | After the project is implemented, | + | Implemented in PHP 8.1: |
- | * the version(s) it was merged into | + | * commit: https:// |
- | * a link to the git commit(s) | + | * docs: TDB |
- | * a link to the PHP manual entry for the feature | + | |
- | * a link to the language specification section (if any) | + | |
===== Acknowledgements ===== | ===== Acknowledgements ===== | ||
To Ilija Tovilo for resolving the parser conflict with by-ref parameters. | To Ilija Tovilo for resolving the parser conflict with by-ref parameters. | ||
+ | |||
+ | To Nikita Popov for reviewing and refactoring the variance code. | ||
===== References ===== | ===== References ===== |
rfc/pure-intersection-types.1620163271.txt.gz · Last modified: 2021/05/04 21:21 by girgias