rfc:nullable_return_types

PHP 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 HHVM compatible syntax to declare nullable return types - ?<type>

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 ?<type> 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 "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 "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.

Enable nullable return types (2/3 majority requited):
Real name yes no
Final result: 0 0
This poll has been closed.
In addition enable nullable argument without default value (1/2 majority required):
Real name yes no
Final result: 0 0
This poll has been closed.

Patches and Tests

Implementation

After the project is implemented, this section should contain

  1. the version(s) it was merged to
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature

References

rfc/nullable_return_types.txt · Last modified: 2017/09/22 13:28 (external edit)