> On Jan 29, 2017, at 3:05 PM, Xiaodi Wu <[email protected]> wrote:
> 
> On Sun, Jan 29, 2017 at 2:40 PM, Matthew Johnson <[email protected] 
> <mailto:[email protected]>> wrote:
> 
>> On Jan 29, 2017, at 2:25 PM, Xiaodi Wu <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> On Sun, Jan 29, 2017 at 2:16 PM, Matthew Johnson <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>>> On Jan 29, 2017, at 2:01 PM, Xiaodi Wu <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> 
>>> On Sun, Jan 29, 2017 at 1:37 PM, Matthew Johnson <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> 
>>> 
>>> Sent from my iPad
>>> 
>>> On Jan 29, 2017, at 12:58 PM, Xiaodi Wu via swift-evolution 
>>> <[email protected] <mailto:[email protected]>> wrote:
>>> 
>>>> Cool. Another avenue of improvement here is relaxing the single-class 
>>>> spelling rule for the sake of composing typealiases.
>>>> 
>>>> As Matthew mentioned, if I have class Base and typealiases Foo = Base & 
>>>> Protocol1 and Bar = Base & Protocol2, it'd be nice to allow Foo & Bar.
>>>> 
>>>> It'd be nice to go one step further: given class Derived : Base, if I have 
>>>> typealiases Foo2 = Base & Protocol1 and Bar2 = Derived & Protocol2, then 
>>>> it could be permitted to write Foo2 & Bar2, since there is effectively 
>>>> only one subclass requirement (Derived).
>>>> 
>>>> As I understand it, the rationale for allowing only one subclass 
>>>> requirement is that Swift supports only single inheritance. Thus, two 
>>>> disparate subclass requirements Base1 & Base2 would make your existential 
>>>> type essentially equivalent to Never. But Base1 & Base1 & Base1 is fine 
>>>> for the type system, the implementation burden (though greater) shouldn't 
>>>> be too awful, and you would measurably improve composition of typealiases.
>>> 
>>> Yes, this is what I was indicating in my post as well.
>>> 
>>> Are you suggesting that Base1 & Base2 compose to a type that is treated 
>>> identically to Never do you think it should be an immediate compiler error? 
>>>  I remember having some discussion about this last year and think somebody 
>>> came up with a very interesting example of where the former might be useful.
>>> 
>>> Last year's discussion totally eludes me for some reason. But sure, if 
>>> deferring the error until runtime is actually useful then why not? In the 
>>> absence of an interesting use case, though, I think it'd be nice for the 
>>> compiler to warn you that Base1 & Base2 is not going to be what you want.
>> 
>> Deferring to runtime isn’t what I mean.  If you try to actually *do* 
>> anything that requires an instance of `Base1 & Based` (which you almost 
>> always would) you would still get a compile time error.
>> 
>> I managed to dig up the example from last year’s thread and it is definitely 
>> a good one:
>> 
>> func intersection<T, U>(ts; Set<T>, us: Set<U>) -> Set<T & U>
>> 
>> The desire is that we are always able to produce a result set.  When T & U 
>> is uninhabitable it will simply be an empty set just like Set<Never> has a 
>> single value which is the empty set.
>> 
>> Currently, Set<Never> is impossible because Never is not Hashable :)
> 
> Ahh, good point.  I hadn’t tried it.  It can easily be made Hashable with a 
> simple extension though - this code compiles today:
> 
> extension Never: Hashable {
>     public var hashValue: Int { return 0 }
> }
> public func ==(lhs: Never, rhs: Never) -> Bool { return false }
> let s = Set<Never>()
> 
>> Since concrete types *can't* be used, this example seems like it'd be of 
>> little use currently. How widely useful would it be to have an intersection 
>> facility such as this when T != U even if that restriction were lifted, 
>> though? Seems like the only real useful thing you can do with generic Set<T 
>> & U> is based on the fact that it'd be Set<Hashable>. Other than those 
>> immediate thoughts, I'll have to think harder on this.
> 
> Sure, it’s possible that this is the only interesting example and may not 
> have enough value to be worthwhile.  But I found it interesting enough that 
> it stuck around in the back of my mind for 8 months! :) 
>  
> Hmm, it had not occurred to me: instantiating a Set<Hashable> is not 
> supported (and you can substitute for Hashable any protocol you want). Thus, 
> for any Set<T> and Set<U> that you can actually instantiate, unless T and U 
> are both classes and one inherits from the other (in which case the generic 
> `intersection<X>(a: Set<X>, b: Set<X>) -> Set<X>` already suffices), Set<T & 
> U> must be the empty set. This is not a very interesting result.

Yes, but this is a limitation due to the fact the existentials for a protocol 
do not conform to the protocol.  In some cases the existential *cannot* conform 
to the protocol but in many cases (especially common cases) it *can*.  It just 
doesn’t today.  There is widespread desire to see this situation improve.

> 
> It generalizes easily to any cases where you have a generic type that is 
> useful despite not necessarily having access to instances of the 
> parameterized type.
> 
> If we allow this, I *think* all uninhabitable types could be unified 
> semantically by making `Never` a protocol and giving them implicit 
> conformance.
> 
>> 
>> This example points even more strongly in the direction of allowing *any* 
>> concrete type to be used, not just classes - even today we could produce 
>> uninhabitable existentials like this using value types.
>> 
>> Here’s the link to the thread: 
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160523/019463.html
>>  
>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160523/019463.html>
>>> 
>>> 
>>>> On Sun, Jan 29, 2017 at 12:41 Austin Zheng <[email protected] 
>>>> <mailto:[email protected]>> wrote:
>>>> The "class comes first" requirement made more sense when the proposed 
>>>> syntax was still "Any<T, U, V>", intentionally mirroring how the 
>>>> superclass and conformances are declared on a class declaration (the 
>>>> archives contain more detailed arguments, both pro and con). Now that the 
>>>> syntax is "T & U & V", I agree that privileging the class requirement is 
>>>> counterintuitive and probably unhelpful.
>>>> 
>>>> Austin
>>>> 
>>>> > On Jan 29, 2017, at 10:37 AM, Matt Whiteside via swift-evolution 
>>>> > <[email protected] <mailto:[email protected]>> wrote:
>>>> >
>>>> > Thanks for writing this proposal David.
>>>> >
>>>> >> On Jan 29, 2017, at 10:13, Xiaodi Wu via swift-evolution 
>>>> >> <[email protected] <mailto:[email protected]>> wrote:
>>>> >>
>>>> >> As Matthew mentioned, the rules can certainly later be relaxed, but 
>>>> >> given that this proposal has the compiler generating fix-its for 
>>>> >> subclasses in second position, is there a reason other than stylistic 
>>>> >> for demanding MyClass & MyProtocol instead of MyProtocol & MyClass?
>>>> >>
>>>> >> From a naive perspective, it seems that if the compiler understands my 
>>>> >> meaning perfectly, it should just accept that spelling rather than 
>>>> >> complain.
>>>> >
>>>> > I had that thought too.  Since ‘and’ is a symmetric operation, requiring 
>>>> > the class to be in the first position seems counter-intuitive.
>>>> >
>>>> > -Matt
>>>> >
>>>> > _______________________________________________
>>>> > 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

Reply via email to