On Wed, 13 Apr 2016 10:53:13 -0600, Levi Morrison wrote: > Continued (hit send by hotkey accident): > > On Wed, Apr 13, 2016 at 10:50 AM, Levi Morrison <le...@php.net> wrote: >> First, some background: several versions of PHP ago authors of >> functions and methods could only restrict types to the array type or a >> class/interface type. We slowly added some other types such as callable >> and primitive types. These tools have been invaluable to those who care >> about restricting the types of their inputs and outputs. This type >> information reduces the code each author has to write if they want to >> restrict to working with certain types and it also provides a form of >> documentation. Overall these features have been well received and are >> considered a good thing to do. >> >> However, as we have added these new restrictions we still cannot >> express exactly what types are permitted in some common cases. >> >> 1. Return types cannot specify the function will return only type T >> or Null. >> 2. Parameter types cannot express that an iterable type is required. >> It's common for functions to work a stream of data and it is irrelevant >> if it is an array or a Traversable object. >> 3. Parameter types cannot express that that the parameter must >> implement two different interfaces. For example, requiring a parameter >> to implement both Countable and Traversable cannot be done. >> >> There are some common work-arounds to these issues: >> >> - Omit the type information and rely on documentation. >> - Check the parameter type inside the function (eg >> `assert(is_array($x) || $x instanceof Traversable)`) >> - Introduce a new type that embodies the restrictions. If this in an >> interface it must be implemented by every object you hope to use the >> restriction with. >> >> In some cases these work-arounds are tolerable. However, some of them >> are really painful. >> >> - Requiring a new supertype is intrusive. Code cannot always be >> changed to use the new supertype. For example: >> - Upstream projects that would not benefit from your changes. >> - Primitives cannot be extended except by altering the engine. >> In these cases a new type has to be introduced that proxies >> behavior to the underlying object/primitive. >> - Relying on documentation can lead to subtle and hard to diagnose >> issues when it is used incorrectly. Erroring immediately is sometimes >> preferable. >> >> All of these issues I've outlined can be nicely resolved by adding two >> new kinds of types to our system: union and intersection types. A union >> type requires the variable to match at least one of the types. An >> intersection type requires the variable to match all of the types. The >> vertical par symbol (OR) is used for unions and ampersand (AND) is used >> for intersections. For example: >> >> function (A | B $var); would require $var to be either type A or >> type B. >> function (A & B $var); would require $var to be type A and type B. >> >> To accommodate the common use-case of returning some type or Null we >> would need to formally allow `Null` as an explicit type: >> >> function (): T | Null; >> >> Since this is a common use case some languages have a short-hand >> notation to represent a union with Null: > > function (): ?T; > > Examples of such languages include Swift, C#, OCaml and Hack (though the > symbol is sometimes in the front and sometimes in the back. > > Later today I will be submitting RFCs for each of these proposals. > Although they can work independently it is helpful to understand the > overall goal and how they fit together, which has been the purpose of > this email. Feedback for each RFC will belong in the thread for that > piece, but discussion about the ideas overall is better suited here.
COOLNESS!! +10 I really like this mindset of a general solution to these stricter types. I think it will present a more consistent "interface" for using types across PHP in the future. In general, this is a more general and elegant solution to nullable type in properties, hints, and return types. I am eager to see what you have in those RFCs. 😃 -- Stephen -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php