====== PHP RFC: Nullable Return Types ====== * Version: 0.9 * Date: 2016-04-06 * Author: Dmitry Stogov, dmitry@zend.com * Status: Draft * First Published at: https://wiki.php.net/rfc/nullable_return_types ===== Introduction ===== PHP 7 introduced optional declaration of function return types. function foo(): int { } However, it didn't make possible to mix declared return type with NULL. This leaded to inability to use return type declarations in many cases, like in the following example of binary-tree where the left and right nodes may be NULL by design. class Node { private $left; private $right; function __construct(Node $left = null, Node $right = null) { $this->left = $left; $this->right = $right; } function getLeft() /* : Node */ { return $this->left; } function getRight() /* : Node */ { return $this->right; } } ===== Proposal ===== I propose to use [[https://docs.hhvm.com/hack/types/type-system#nullable|HHVM compatible syntax]] to declare nullable return types - **?** So the previous example will look like the following: class Node { private $left; private $right; function __construct(Node $left = null, Node $right = null) { $this->left = $left; $this->right = $right; } function getLeft(): ?Node { return $this->left; } function getRight(): ?Node { return $this->right; } } ==== Nullable Arguments without Default Values ==== Usage of the same **?** syntax for arguments (and later properties) is not the primary goal of this RFC, because arguments already may be declared as "nullable", using NULL default value (the same may be done for properties). It's also possible to add the same syntax for arguments as it was proposed in [[https://wiki.php.net/rfc/nullable_types|"Declaring Nullable Types" RFC]] function foo(int $a = null) { // already works in 7.0 } function foo(?int $a) { // we may make this work as well } ==== Inherited Method Compatibility Rules ==== Nullable types won't change anything in inherited method compatibility rules. We will still use Covariance for return types and Contravariance for arguments. This means, that methods with nullable return types may be overridden by methods with non-nullable, but methods with non-nullable return types can't be overridden by methods with nullable. ===== Backward Incompatible Changes ===== NONE ===== Proposed PHP Version(s) ===== This RFC targets PHP version 7.1. ===== Open Issues ===== NONE ===== Future Scope ===== ==== Union Types ==== The [[https://wiki.php.net/rfc/union_types|"Union Types" RFC]] proposes different syntax, but misses implementation for more than a year. It provides smarter, but less usable (in my opinion) syntax. function foo(): int|null { } I don't see a big reason to extend PHP with both possible syntaxes, so this RFC competes with "Union Types" and only one should be selected. The implementation of this RFC is very simple and efficient. "Union Types" RFC, on the other hand, will have to make a decision about support for multiple class names in a single declaration and this decision may lead to inconsistency or expensive implementation (then we will have to keep many class names, and then in run-time perform multiple class lookups and checks). ===== Proposed Voting Choices ===== The vote will start on April 25 and finish on May 9. * yes * no * yes * no ===== Patches and Tests ===== [[https://github.com/php/php-src/pull/1851|https://github.com/php/php-src/pull/1851]] ===== Implementation ===== After the project is implemented, this section should contain - the version(s) it was merged to - a link to the git commit(s) - a link to the PHP manual entry for the feature ===== References ===== - [[https://wiki.php.net/rfc/nullable_types|"Declaring Nullable Types" RFC]] - [[https://wiki.php.net/rfc/union_types|"Union Types" RFC]] - [[https://docs.hhvm.com/hack/types/type-system#nullable|Nullable Types in HHVM]] - [[https://wiki.php.net/rfc/typed-properties|"Typed Properties" RFC]] - [[https://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29|Covariance and contravariance]]