> On May 18, 2016, at 4:17 PM, Austin Zheng via swift-evolution > <[email protected]> wrote: > > I'm not sure what your objections actually are, but my responses are inline.
Your responses are exactly what mine would be. For a second I was worried that I missed something when reading the latest draft! :) > > On Wed, May 18, 2016 at 1:57 PM, Adrian Zubarev via swift-evolution > <[email protected] <mailto:[email protected]>> wrote: >>> So without any initial constraints how would one use this generic function?? >>> >>> extension UIButton: ProtocolA {} >>> >>> let button = UIButton() >>> let shadowedButton: ProtocolA = UIButton() >>> >>> // creates a set of a least one element if the generic type could be >>> inferred >>> func unionIfPossible<T, U>(_ a: T, _ b: U) -> Set<Any<T, U>>? { /* merge >>> somehow if possible */ } >> >> You would not be able to form Any<T, U> here because T and U are generic >> arguments unknown. We don’t accept those, only `class`, specific classes, >> and specific protocols (and recursively, other Any). > > Why would Any<…> does not work with the generic system here? To me it makes > no sense, I as a developer would assume I can use a generic Type anywhere a > type can be used (protocols and their associated types are a special case). > > Because what existentials are trying to model and what generic type > parameters are trying to model are two different things. You already cannot > use arbitrary types within a Any<> existential as the proposal stands. > > This doesn't currently work in Swift, and it shouldn't: "func foo<A, B>() -> > protocol<A, B>". There is no useful way to generically compose instances of > two protocol types at runtime to form an instance of a type that conforms to > both protocols, like there is a way to compose instances of two types to form > a tuple containing those types. Therefore, writing a generic function to do > this makes no sense. > > > I would assume that: > > func foo<T: UIView>(value: Any<T, SomeProtocol>) > > should be equal to (without the need of generics): > > func foo(value: Any<UIView, SomeProtocol>) > >>> >>> // this should be valid because the compiler will assume Any<UIView, >>> ProtocolA> where T == UIView and U == ProtocolA >>> let merged_1: Set<Any<UIView, ProtocolA>> = unionIfPossible( /* UIView >>> subtype */ button, /* ProtocolA */ shadowedButton) >>> >>> // this won’t be possible because of the restriction >>> let merged_2: Set<Any<UIView, ProtocolA>> = unionIfPossible(shadowedButton, >>> button) >>> >>> Any<UIView, ProtocolA> != Any<ProtocolA, UIView> isn’t right. Sure it may >>> feel right for readability but the types should be equal. >>> >>> "Can be any class type that is a UIView or a subclass of UIView, that also >>> conforms to ProtocolA.“ == "Type that conforms to ProtocolA and that is a >>> UIView or a subclass of UIView.“ >>> >>> This is also a nesting problem where you will be forced to choose the right >>> place inside the angle brackets where to add a nested `Any<…>`. >>> >>> class A: ClassB, ProtocolA {} >>> >>> Any<A, Any<ClassB, ProtocolA>> == A != Any<Any<ClassB, ProtocolA>, A> == >>> Any<ClassB, ProtocolA, A> which should be reorder by the compiler and >>> inferred as A >> >> `Any<Any<ClassB, ProtocolA>, A>` is not allowed because if a class is >> provided it must come first. >> >> `Any<ClassB, ProtocolA, A>` is not allowed because it contains more than one >> class. > > Not true, take a look at the nested section of the proposal again. > > We discussed that this is valid: > > // Allowed, but pointless. > // Identical to Any<ProtocolA, ProtocolB> > let b : Any<Any<ProtocolA, ProtocolB>> > > This implies that also this would be valid: > > Any<Any<ClassA, ProtocolA>> inferred as Any<ClassA, ProtocolA> > > Yes, this is valid. > > > There is another example: > > // Can be any type that is a UITableView conforming to ProtocolA. > // UITableView is the most specific class, and it is a subclass of the other > // two classes. > let a : Any<UIScrollView, Any<UITableView, Any<UIView, ProtocolA>>> > > Which followed by the mentioned rule can als be: > > Any<UIScrollView, UITableView, Any<UIView, ProtocolA>> or > Any<UIScrollView, UITableView, UIView, ProtocolA> > > This would force us to allow multiple classes inside Any<…> if there is a > inheritance relationship between them. > > Yes. As explained in the proposal, there is already a way to handle resolving > the single 'effective' class constraint. You can only 'explicitly' declare > one class constraint, but you can pull in other class constraints from nested > existentials for the sake of making composition easier. In the end it doesn't > matter, because if the class constraints don't form a valid inheritance > hierarchy the compiler will complain, and if they do the most specific type > will be chosen. > > > And because this is a inheritance relationship it can be simplified to: > > Any<UITableView, ProtocolA> which is valid. > > And by the way since the order in your proposal would matter, this example > won’t work at all, because its not: > > Any<UITableView, Any<UIScrollView, Any<UIView, ProtocolA>>> > > The order does not affect the semantic meaning of the existential. There is a > section in the proposal on how existentials are conceptually 'reduced' from > whatever form they take when the programmer types them in, please read it. I > am not proposing a macro system. The compiler does not do textual replacement > in order to flatten nested existential definitions. > > This is also why it makes no sense to have a generic "Any<T, U>", because > such a type is identical to "Any<U, T>", which is not true for any other > generic type or aggregate type in Swift. > > > In my proposal I explicitly banned multiple reference types and inheritance > branches like this. I would need to simplify that type to Any<UITableView, > ProtocolA> by myself. > Ingeneral this is a good idea, but it makes nesting (with typealiases) almost > impossible, when there are some relationship like in the above example. > > > -- > Adrian Zubarev > Sent with Airmail > > _______________________________________________ > swift-evolution mailing list > [email protected] <mailto:[email protected]> > https://lists.swift.org/mailman/listinfo/swift-evolution > <https://lists.swift.org/mailman/listinfo/swift-evolution> > > > _______________________________________________ > swift-evolution mailing list > [email protected] <mailto:[email protected]> > https://lists.swift.org/mailman/listinfo/swift-evolution > <https://lists.swift.org/mailman/listinfo/swift-evolution>
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
