This is an old revision of the document!
PHP RFC: Void Return Type
- Version: 0.1.1
- Date: 2015-02-14
- Author: Andrea Faulds, ajf@ajf.me
- Status: Withdrawn
- First Published at: http://wiki.php.net/rfc/void_return_type
Introduction
The Return Types RFC has introduced return types to PHP. While there is already a means to specify that any value may be returned (by omitting the return type), there is no means to specify that no value can be returned, unlike many other languages with return types. This is unfortunate, as this can be useful for documentation and error-checking purposes. In particular, it makes it clear that a function performs an action, rather than producing a result. This RFC proposes the introduction of a void
return type for this purpose.
Proposal
Support for a new void
return type is added. It requires that a function not return any value:
function should_return_nothing(): void { return 1; // Catchable fatal error: should_return_nothing() must not return a value, integer returned } should_return_nothing();
It accepts either an implicit return, or an explicit value-less return:
function lacks_return(): void { // valid } lacks_return(); function returns_nothing(): void { return; // valid } returns_nothing();
However, it does not accept returning a NULL
value:
function returns_null(): void { return NULL; // Catchable fatal error: returns_null() must not return a value, null returned } returns_null();
This might seem odd given that return;
is technically equivalent. However, allowing NULL
would also allow this:
function returns_null2(): void { $x = some_computation(); // produces null most of the time return $x; // Catchable fatal error: returns_null() must not return a value, null returned } returns_null2();
If PHP were to allow returning a value which evaluates to null, we'd have to allow the above, and this doesn't make sense: a void
function shouldn't be trying to return a value.
Furthermore, there is a code style point to be made here. return;
signals different intent to return NULL;
. The former returns control flow and, while it does implicitly produce a null return value, signals that the return value is unimportant. The latter, on the other hand, explicitly produces a null return value, suggesting that the null value is significant.
Like all functions which do not explicitly return a value in PHP, evaluating a call to a void
return-typed function (“void function” from here onwards) results in null:
function summonElePHPants(): void { echo "ElePHPants of the world, unite!"; } $useless_value = summonElePHPants(); var_dump($useless_value); // NULL
This is unlike void functions in some other languages, which prevent the use of such functions in expressions.
While it would be theoretically possible to prevent the use of void functions in expressions in PHP, this RFC does not do so for the following reasons:
- PHP doesn't do this for built-in or extension PHP functions (aka “internal functions”) which return no value, and which are documented using “void”
- For the entirety of PHP's history, all function calls have been valid expressions, and changing this will break code which relies on that fact
- In particular, this would lead to unpredictable behaviour with callbacks
- Passing along the result of a callback with
return $somecallback(...);
is a common pattern and would be broken by this change
- Void return types could not be added to existing functions without possibly breaking code which calls them
- This would introduce an unnecessary distinction between function call expressions and function call statements
- This error cannot be caught at compile-time, because PHP is a dynamic language
- Unlike all other return types, this would be placing a restriction on the caller
- Implementing this in the Zend Engine would create problems:
- This would require checking every function call to see whether its result is used, which could result in a slowdown for non-void calls
- We currently do not have a mechanism to tell whether a function call's result is used - this would have to be added
Finally, IDEs and code linters could easily check for using the result of a void function call and warn the user, so it does not necessarily have to be enforced by the language itself.
The void
type cannot be used for parameters:
function foobar(void $foo) { // Fatal error: void cannot be used as a parameter type }
A void
return type cannot be changed during inheritance. You can see this as either because return types are invariant, or because they are covariant and nothing is a subclass of void
.
class Foo { public function bar(): void { } } class Foobar extends Foo { public function bar(): array { // Fatal error: Declaration of Foobar::bar() must be compatible with Foo::bar(): void } }
Backward Incompatible Changes
Like the scalar types proposed by the Scalar Type Hints RFC, the void
return type does not become a reserved word, but is instead restricted from use in class and interface names. This avoids confusion while minimising backwards-compatibility breakage.
Proposed PHP Version(s)
This is proposed for the next major version of PHP, currently PHP 7.
Proposed Voting Choices
As this is a language change, a 2/3 majority is required. The vote is a straight Yes/No vote for accepting the RFC and merging the patch.
Patches and Tests
There is a patch for php-src with tests here: https://github.com/php/php-src/pull/1084 It is based on patch used by the Scalar Type Hints RFC, since it already contains the infrastructure for reserving class and interface names for parameter and return types. However, should that RFC fail to pass, it would be possible to base the patch directly on master.
There is currently no patch for the language specification.
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
Changelog
- v0.1.1 - Detailed implicit null return value
- v0.1 - Initial version