Please excuse me for my horrible writing. I guess I’m to tired right now and 
write a ton strange sentences and typos. :/

Anyways, when the right time comes, I’ll fully support this feature. Any is 
defiantly worth being part of Swift.

Good n8 everyone.

-- 
Adrian Zubarev
Sent with Airmail

Am 18. Mai 2016 bei 23:30:57, Adrian Zubarev (adrian.zuba...@devandartist.com) 
schrieb:

Okay I got it now, generics made my head spin. I also received no feedback on 
my proposal to that specific case, which I misunderstood. Thank you for 
clarifying that to me. That said it makes now sense to force the first 
requirement, which I dropped in my proposal. 

I’ll fix that tomorrow.

I’m fine with your proposal now. =) 

-- 
Adrian Zubarev
Sent with Airmail

Am 18. Mai 2016 bei 23:17:47, Austin Zheng (austinzh...@gmail.com) schrieb:

I'm not sure what your objections actually are, but my responses are inline.

On Wed, May 18, 2016 at 1:57 PM, Adrian Zubarev via swift-evolution 
<swift-evolution@swift.org> 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
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to