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