This is an old revision of the document!
PHP RFC: Return Type-hinting
- Version: 0.1
- Date: 2014-03-20
- Author: Levi Morrison levim@php.net
- Status: Draft
- First Published at: https://wiki.php.net/rfc/returntypehinting
Introduction
Many developers would like to be able to declare the type of a return value. The basic idea has been proposed in at least three RFCs and has had a few other discussions (see references).
Return type-hinting has several motivators and use-cases:
- Preventing unintended return types
- Enforcing return types on interface implementations1).
- Documenting return type information that is not easily invalidated (unlike comments).
Proposal
This proposal adds an optional return type-hint to all types of function declarations including closures, functions, interface method declarations and class declarations.
Example of function_declaration_stmt
:
"function" ["&"] T_STRING "(" parameter_list ")" [":" (T_STRING | array | callable)] "{" inner_statement_list "}"
Variance and Signature Validation
The enforcement of the type-hint during inheritance will be covariant. Covariant return types is considered to be type sound and is used in many other languages2). The covariance allows an overrider to declare a return type that is a subclass of the original return type; this is illustrated in the examples below.
If a mismatch is detected during compile time (eg a class improperly overriding a return type) then E_COMPILE_ERROR
will be issued. If a type mismatch is detected when the function returns then E_RECOVERABLE_ERROR
will be issued.
Position of Type-hint
The two major conventions in other programming languages for placing return type information are:
- Before the function name:
<return_type> name(){}
- After the parameter list:
name() <return_type> {}
The former position has been proposed in the past and the RFCs were either declined or withdrawn. One cited issue is that many developers wanted to preserve the ability to search for function foo
to be able to find the definition for foo
.
The latter position is used in some functional languages; Facebook's Hack language also declared their return types here. Declaring the return type after the parameter list will have no conflicts in the parser.
Examples
Here are some examples of valid and invalid uses.
Examples of Valid Use
// Covariant return-type: interface Collection { function map(callable $fn): Collection; } interface Set extends Collection { function map(callable $fn): Set; }
// Overriding a method that did not have a return type: interface Iterator { function rewind(); function valid(); function key(); function current(); function next(); } class CommentsIterator implements Iterator { function current() : Comment; }
Examples of Invalid Use
// return type does not match type-hint function get_config(): array { return null; }
// invalid type-hint function answer(): int { return 42; }
// Missing return type on override: interface UserGateway { function find($id) : User; } class UserGateway_MySql implements UserGateway { function find($id); // must return User or subtype of User }
// Defining a return type on a Generator function filter(Traversable $in, callable $filter): array { foreach ($in as $key => $value) { yield $filter($key, $value); } }
Multiple Return Types
This proposal specifically does not allow multiple return type-hints; if such a feature is needed then use PHP's existing dynamic nature and leave off the return type.
Differences from Past RFCs
This proposal differs from past RFCs in several key ways:
- We keep the current type-hint options. Past proposals have suggested new types such as
void
,int
,string
orscalar
. - We allow type-hints on all function types3). Will Fitch's proposal suggested adding it for methods only.
- We keep the current search patterns. You can still search for
function foo
to findfoo
's definition; all previous RFCs broke this. - We do not modify or add keywords. Past RFCs have proposed new keywords such as
nullable
and more. We still require thefunction
keyword.
Open Issues
Allowing NULL for Objects
Consider the following function:
function foo() : DateTime { return null; }
It declares that it will return DateTime
but returns null
. In type-hints for parameters this would fail unless = null
was appended to the end. It is a common pattern to return null
to indicate that there is no result for something that normally returns an object.
We can introduce some syntax to allow null
to be passed.
One proposal is to use |
function foo() : DateTime|null { return null; }
I personally feel that this gives the impression that we allow multiple return types. This proposal explicitly does not allow multiple return types.
Another option is to use Hack's syntax:
function foo() : ?DateTime { return null; }
Another option is to use a C# inspired syntax:
function foo() : DateTime? { return null; }
We could choose to delay this decision to a later date; not allowing null
would be future-compatible with such a decision.
Generators
According to Nikita Popov, generators have a concept of a return value that may be exposed at some future point. His recommendation is to not allow return types on generators as they may conflict with future work in this area. If type-hinting on generators were to work the same way it does on other functions then the only valid return type would be Generator
; therefore not allowing return types on generators is not a loss at all.
Other Impact
On Backward Compatiblity
This RFC is backwards compatible with previous PHP releases.
On SAPIs
There is no impact on any SAPI.
On Existing Extensions
There is no known impact on extensions.
On Performance
Until a patch is completed (Joe Watkins has offered to provide one) the impact on performance is unknown.
Proposed PHP Version(s)
As there are no known BC breaks this RFC targets PHP 5.7. If a BC break is discovered it will be proposed for PHP 6.0.
Proposed Voting Choices
This RFC modifies the PHP language syntax and therefore requires a two-third majority of votes.
Patches and Tests
Currently there isn't a patch; Joe Watkins has offered to provide one.
References
- Return value and parameter type hint by Felipe; 2008. Mail Archive.
- Return Type-hint by Felipe; 2010. Mail Archive
- Method Return Type-hints by Will Fitch; 2011. Mail Archive.
Future Work
- Reflection support
- Consider allowing extensions to define type-hints for return values.