> 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
