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

Reply via email to