This is an old revision of the document!
PHP RFC: Sum Types
- Version: 0.1
- Date: 2015-02-14
- Author: Levi Morrison levim@php.net
- Status: Draft
- First Published at: http://wiki.php.net/rfc/sum_types
Introduction
In PHP 5.1 the ability to provide explicit types for parameters was added to PHP. It supported classes, interfaces and arrays. In PHP 5.4 the callable
pseudo-type was added. The ability to provide explicit return types was added in PHP 7 but did not allow returning something or null, a commonly requested feature. Later an RFC for adding explicit scalar types was proposed and a few people wanted to know why there isn't a numeric
type to handle the case where int
and float
are both accepted. I have personally wanted the ability to type against both array
and Traversable
in some of my libraries.
All of these requests and discussions suggest that the ability to accept multiple types for a parameter or return type could be useful. This RFC is an investigation into the feasibility of this idea and to flesh out the impact it would have on other parts of PHP.
Proposal
This RFC proposes the ability to define multiple types for a parameter or return type and calls them “sum types”. Here is an example of a parameter accepting both array
and Traversable
simultaneously:
function (array|Traversable $in) { foreach ($in as $value) { echo $value, PHP_EOL; } }
Assuming that we allow a type of null
we could use this feature to avoid special syntax for explicit nullable types; instead of ?Foo
we can use Foo|null
.
Proposed PHP Version(s)
It is not yet known if this requires backwards compatibility breaks. It could theoretically target PHP 7.NEXT but possibly should wait until PHP 8 (or whatever we call it).
RFC Impact To Opcache
There is not yet an implementation, but this will certainly necessitate changes in opcache.
Open Issues
Weak Scalar Types
If PHP adds explicit weak scalar types there is a question of how things will get converted in some situations. As an example, if we have a sum type of int
and float
and are passed the string “10” how is it converted?
function f(int|float $number) { return $number * 2; } f("10");
Would it be converted to int(10)
or float(10)
, since either is acceptable? Does it matter given they are both acceptable?
This issue would be avoided if a parameter type exactly matches the input type or if PHP has strict scalar types.
Long Type Names
Since you can create a chain of types the names can get quite lengthy. Even the fairly short sum type of array|Traversable
can be repetitive to type out. Should a method to provide type aliases exist? It may be helpful to look at HHVM's Type Aliasing.
Reflection
There isn't any part of our current Reflection extension that can deal with sum types and I have not yet given it any thought.
Or False
Peter Cowburn (salathe) has suggested that being able to explicitly use |false
for return types could be helpful as this is a common idiom in PHP's standard functions. As an example, the function signature for strpos
could change:
Future Scope
This sections details areas where the feature might be improved in future, but that are not currently proposed in this RFC.
Proposed Voting Choices
This RFC requires that two-thirds of voters vote in favor of the RFC to pass.
Patches and Tests
Presently no patch.
References
Links to external references, discussions or RFCs
Rejected Features
Keep this updated with features that were discussed on the mail lists.