Sorry for top-posting... it looks like GMail top-posts everything that
doesn't have a reply character right before the inherited (replied email),
which i just did.

On Fri, Apr 29, 2016 at 10:26 AM, guilhermebla...@gmail.com <
guilhermebla...@gmail.com> wrote:

>
>
> On Fri, Apr 29, 2016 at 4:55 AM, Jesse Schalken <m...@jesseschalken.com>
> wrote:
>
>>
>>
>> On Wed, Apr 27, 2016 at 6:50 AM, guilhermebla...@gmail.com <
>> guilhermebla...@gmail.com> wrote:
>>
>>> Hi all,
>>>
>>> Yesterday I spent a considerable 2h talking about Generics in Doctrine
>>> channel.
>>> We discussed the specifics of each boundary that PHP's implementation
>>> could
>>> take advantage. Here are our findings, which I'll illustrate using Java
>>> equivalents:
>>>
>>> 1- Upper bounds (T extends A)
>>>
>>> We all understood they're required. Whenever you mention class Foo<T is
>>> A>
>>> {}, we're talking that T can be A or any of its subtypes.
>>> Also, we debated over intersection types. It's an edge case, and its
>>> support could be done as a subsequent RFC once union and intersection
>>> types
>>> gets resolved.
>>>
>>> 2- Lower bounds (T super A)
>>>
>>> It was just not possible to come up with a single use case or
>>> possibility.
>>> It not only violates Liskov, but it also doesn't make any sense in the
>>> context of PHP.
>>> When we debate about Java, it does make sense because of polymorphism and
>>> the requirement removal of implementing multiple methods.
>>>
>>> 3- Unbounded wildcards (?)
>>>
>>> It wouldn't be necessary in the context of PHP. Why?
>>> Once we introduce Generics, the difference between process(List $list)
>>> and
>>> process(List<?> $list) would be none, as due to PHP's nature.
>>>
>>> 4- Upper bounded wildcard (? extends A)
>>>
>>> Again, invalid in the context of PHP. Let me explain why...
>>> In Java context, whenever you declare something as List<A>, you can only
>>> add As to the list, but no subtypes. When you declare List<? extends A>,
>>> you can add A and also any of its subtypes.
>>> PHP is loose in this restriction, so there's no way of strict-ing to
>>> only A
>>> but not subtypes. Defining as List<A> would be enough, and PHP wouldn't
>>> support adding A and A only.
>>>
>>
>>
>> You can add subtypes of A to a List<A> in Java. What List<? extends A>
>> means is that the list itself may be a list of any type, provided that type
>> is compatible with A. So if B extends A, List<B> is compatible with List<?
>> extends A>, and when reading items you can assume they will be compatible
>> with A (since B extends A) but you can't add an A (because it's actually a
>> list of Bs).
>>
>>
> Wrong. This is documented here
> https://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html
> and specifically states:
>
> To write the method that works on lists of Number and the subtypes of
>> Number, such as Integer, Double, and Float, you would specify List<?
>> extends Number>. The term List<Number> is more restrictive than List<?
>> extends Number> because the former matches a list of type Number only,
>> whereas the latter matches a list of type Number or any of its
>> subclasses.
>
>
>
>
>> Similarly, List<? super A> means it may be a list of A or some super type
>> of A. So if A extends C, List<C> is compatible with List<? super A>, and
>> you can add an A (because A is compatible with C) but when reading items
>> you can't assume they're going to be As (because it's actually a list of
>> Cs).
>>
>>
> Again wrong. The lower bound also respect the rules of upper bound
> wildcard. If you return a List<C>, you cannot add an A instance.
>
>
>> This is my understanding of variance behaviour and notation in the three
>> languages I'm most familiar with:
>>
>> Covariance (Foo<Sub> is a subtype of Foo<Super>)
>>
>> Java  Foo<? extends T> at usage  Methods accepting T as parameter cannot
>> be called
>> Hack  Foo<+T> at declaration     Methods accepting T as parameter cannot
>> be defined
>> C#    Foo<out T> at declaration  Methods accepting T as parameter cannot
>> be defined
>>
>>
>> Contravariance (Foo<Super> is a subtype of Foo<Sub>)
>>
>> Java  Foo<? super T> at usage   Methods returning T can be called but
>> return Object
>> Hack  Foo<-T> at declaration    Methods returning T cannot be defined
>> C#    Foo<in T> at declaration  Methods returning T cannot be defined
>>
>>
>> Invariance (no relationship between Foo<Super> and Foo<Sub>)
>>
>> Java  Foo<T> at usage           Methods accepting T and returning T can
>> both be called
>> Hack  Foo<T> at declaration     Methods accepting T and returning T can
>> both be defined
>> C#    Foo<T> at declaration     Methods accepting T and returning T can
>> both be defined
>>
>>
>> (There are more general rules for method signatures when T is used as the
>> parameter for another generic type, but I can't remember what they are.)
>>
>> I can't see variance mentioned in the RFC, but when I asked about it when
>> the RFC was posted on Reddit, Rasmus said the type parameters would always
>> be covariant, so Foo<A> in PHP as an annotation would be equivalent to
>> Foo<? extends A> in Java, even though this has the opposite of the
>> intended effect if Foo has methods which accept a parameter of the generic
>> type, such as something like List<T>::add(T $element), Callback<T>::run(T
>> $data) or Box<T>::setContents(T $contents).
>>
>>
> Rasmus is purely following already defined PHP covariance definition that
> currently exists for type hinting into generic types.
> Java differs from that and accept covariance for type definitions, but
> restricts for generic types.
>
>
>> My view is that PHP's generics should be invariant to start with (generic
>> arrays can still be covariant of course, since they are passed by value),
>> maintaining type safety and matching the behaviour of Java, Hack and C# for
>> type parameters without variance annotations, and variance syntax should be
>> added later as another RFC as demand arises.
>>
>>
>>
>> 5- Lower bounded wildcard (? super A)
>>>
>>> Applies the same concept of #2. PHP doesn't need it as it doesn't fully
>>> support polymorphism.
>>>
>>> 6- Reflection
>>>
>>> We discussed over an example I extracted from a piece of code I currently
>>> work on. We came with several ideas, but couldn't wrap up (but we're
>>> 80%) a
>>> valid approach. The example we debated was this one:
>>> https://gist.github.com/guilhermeblanco/56ec0e11e7b029c2cfdcaf6fe2323742
>>>
>>>
>>>
>>>
>>> So I'll have to say sorry for poking around of "missing implementation"
>>> while in reality most of them cannot be applied in the context of PHP.
>>> I've reviewed the RFC again and it mostly makes sense surrounding
>>> boundaries. I still have to talk about diamond operator and constructor
>>> generic type.
>>>
>>>
>>> []s,
>>>
>>>
>>> On Tue, Apr 26, 2016 at 4:15 PM, Robert Stoll <p...@tutteli.ch> wrote:
>>>
>>> >
>>> >
>>> > > -----Ursprüngliche Nachricht-----
>>> > > Von: Rasmus Schultz [mailto:ras...@mindplay.dk]
>>> > > Gesendet: Montag, 25. April 2016 18:09
>>> > > An: Josh Di Fabio
>>> > > Cc: Dominic Grostate; Guilherme Blanco; Mathieu Rochette; Ben
>>> Scholzen
>>> > 'DASPRiD'; Sara Golemon; PHP internals; Mathieu
>>> > > Rochette
>>> > > Betreff: Re: [PHP-DEV] [RFC:generics]
>>> > >
>>> > > > I really don't like 'as' in this context, even if Hack uses it, as
>>> it
>>> > > > doesn't reflect in English terms what the code is doing. As others
>>> > > > have already said, it reads as if 'T' is being aliased to 'Bar'.
>>> > >
>>> > > I second that.
>>> > >
>>> > > I hear the concerns about adding another reserved word "is" though,
>>> so
>>> > I'd like to suggest simply using a ":" ... as in:
>>> > >
>>> > >     class A<T : T1> { ... }
>>> >
>>> > In this case I would suggest to use class A<T <: T1> which leaves room
>>> > open to define lower bounds later on (either with <: as well or with
>>> :> as
>>> > in scala)
>>> >
>>> > >
>>> > > Consistent with return type-hints, it should feel like home?
>>> > >
>>> > > For sure nobody wants to type out "instanceof", and (as pointed out
>>> in
>>> > the RFC) the instanceof operator checks the type of
>>> > > an object, which is *not* what this is doing - a type argument is
>>> not an
>>> > "instance of" anything. The ":" is more neutral in that
>>> > > regard maybe?
>>> > >
>>> > >
>>> > > On Thu, Apr 21, 2016 at 10:32 AM, Josh Di Fabio <
>>> joshdifa...@gmail.com>
>>> > wrote:
>>> > > > On Wed, Apr 20, 2016 at 8:17 PM, Dominic Grostate
>>> > > > <codekest...@googlemail.com> wrote:
>>> > > >> Thanks for you're input everyone.
>>> > > >>
>>> > > >> So far, we have read some ideas for handling upper bounds, or
>>> > > >> multiple there of.
>>> > > >> The preferred keywords appear to be either "as" or "instanceof".
>>> > > >>
>>> > > >> class Foo<T as Bar> {}
>>> > > >> class Foo<T instanceof Bar> {}
>>> > > >>
>>> > > >> We would like to know for sure then if everyone is largely against
>>> > > >> the addition of an "is" keyword, in favour of one of the other
>>> two.
>>> > > >>
>>> > > >
>>> > > > I really don't like 'as' in this context, even if Hack uses it, as
>>> it
>>> > > > doesn't reflect in English terms what the code is doing. As others
>>> > > > have already said, it reads as if 'T' is being aliased to 'Bar'.
>>> > > >
>>> > > > On Wed, Apr 20, 2016 at 8:17 PM, Dominic Grostate
>>> > > > <codekest...@googlemail.com> wrote:
>>> > > >> Thanks for you're input everyone.
>>> > > >>
>>> > > >> So far, we have read some ideas for handling upper bounds, or
>>> > > >> multiple there of.
>>> > > >> The preferred keywords appear to be either "as" or "instanceof".
>>> > > >>
>>> > > >> class Foo<T as Bar> {}
>>> > > >> class Foo<T instanceof Bar> {}
>>> > > >>
>>> > > >> We would like to know for sure then if everyone is largely against
>>> > > >> the addition of an "is" keyword, in favour of one of the other
>>> two.
>>> > > >>
>>> > > >> ----------------
>>> > > >>
>>> > > >> There is also a desire to include unions and intersections.
>>> > > >> Presently though, this feature feels tied in with
>>> > > >> https://wiki.php.net/rfc/union_types meaning if union types are
>>> > > >> approved, then generics would have to support them as well.
>>> Likewise
>>> > > >> if this feature becomes approved in generics, it would make sense
>>> to
>>> > > >> support them in regular type hints as well.
>>> > > >>
>>> > > >> ----------------
>>> > > >>
>>> > > >> The RFC makes a reference to generic closures, which may look
>>> > > >> something like
>>> > > >> this:
>>> > > >>
>>> > > >> function my_function(callable<Foo, Bar> $func) {
>>> > > >>
>>> > > >> }
>>> > > >>
>>> > > >> However, an RFC already exists which is very similar to this
>>> feature
>>> > > >> at https://wiki.php.net/rfc/callable-types
>>> > > >> As it currently standards these RFCs appear incompatible with each
>>> > > >> other (please correct me if I am wrong).
>>> > > >>
>>> > > >> My question about this is would you prefer the generics RFC
>>> exclude
>>> > > >> this part in favour of a separate or later RFC.
>>> > > >> Initially the proposal included generic arrays "array<string>".
>>> > > >> However to ease the implementation it was decided that should be a
>>> > separate feature.
>>> > > >> So we'd like to find out if everyone else feels the same way about
>>> > > >> callable types.
>>> > > >>
>>> > > >> ----------------
>>> > > >>
>>> > > >> This RFC currently doesn't specify in detail how reflection would
>>> > > >> work.  We have attempted a few API designs, but due to generic
>>> > classes being ...
>>> > > >> generic, it is difficult to find a suitable way to glean
>>> information
>>> > > >> about a class in a backwards compatible manner.  So we will need
>>> some
>>> > > >> help on this one.
>>> > > >>
>>> > > >> -----------------
>>> > > >>
>>> > > >> Aside from these top issues on our own list, however does everyone
>>> > > >> feel about the proposal in general?
>>> > > >> As the RFC is still in draft, we will continue to make changes to
>>> it
>>> > > >> as more popular idea pop up, so please continue.
>>> > > >>
>>> > > >> Thanks.
>>> > > >>
>>> > > >> PS: I wasn't properly subscribed to the mailing list, so I missed
>>> a
>>> > > >> few important messages that were mailed directly to internals, but
>>> > > >> hopefully I've managed to fix that now.
>>> > >
>>> > > --
>>> > > PHP Internals - PHP Runtime Development Mailing List To unsubscribe,
>>> > visit: http://www.php.net/unsub.php
>>> >
>>> >
>>> >
>>>
>>>
>>> --
>>> Guilherme Blanco
>>> Lead Architect at E-Block
>>>
>>
>>
>
>
> --
> Guilherme Blanco
> Lead Architect at E-Block
>



-- 
Guilherme Blanco
Lead Architect at E-Block

Reply via email to