Redundant introduction aside, I want to have something like this:
let collection : Any<Sequence where .Iterator.Element == String> = ...
or
let collection : Sequence<where .Iterator.Element == String> = ...
This is referred to as "Generalized existentials" in Apple's Generics Manifesto. (I think) I really need this for a number of use cases and this:
protocol 'P' can only be used as a generic constraint because it has Self or associated type requirements.
makes "the first Protocol Oriented Language" be cumbersome for me to understand. Lack of this makes me fight Swift's type system and create adverse generic "abstract" classes where there should be a protocol with associatedtype
.
Here's one example, that hit me the most, delegate for a generic class:
protocol GenericClassDelegate : class {
associatedtype ItemType
func didDoThat(who : GenericClass<ItemType>)
}
class GenericClass<T> {
weak var delegate : GenericClassDelegate<where .ItemType == T>? // can't do that
func notify() {
delegate?.didDoThat(who: self)
}
}
While I can describe GenericClassDelegate
protocol, I (currently in Swift 3) can't have a variable or constant of that type (or any type conforming to restrictions).
Don't confuse this question with How to use generic protocol as a variable type or Swift delegate protocol for generic class, as my questions are:
- Are there any proposals or discussions currently present on introducing Generalized Existentials into Swift, what are the plans? If no, how can I participate and affect this?
- If Swift was designed that way (with Associated Types, but without Generalized Existentials), maybe it implies some architectural shift. What am I expected to replace delegation pattern with?
P.S. Don't suggest thunks with type erasure when you capture delegate's function in a closure, that is so much wrong and misleading, I'd even call it a crutch.
Accidentally found another solution, but I'm not satisfied with it completely:
protocol GenericClassDelegate : class {
associatedtype ItemType
func didDoThat(who : GenericClass<ItemType, Self>)
}
class GenericClass<T, Delegate : GenericClassDelegate> where Delegate.ItemType == T {
weak var delegate : Delegate?
func notify() {
delegate?.didDoThat(who: self)
}
init(_ delegate : Delegate?) {
self.delegate = delegate
}
}
// Delegates must be final classes, otherwise it does not compile
// because I used Self in GenericClassDelegate
final class GenericClassDelegateImp<T> : GenericClassDelegate {
typealias ItemType = T
func didDoThat(who: GenericClass<T, GenericClassDelegateImp>) {
print(who)
}
}
// Usage:
var delegate = GenericClassDelegateImp<Int>()
var genericClass = GenericClass<Int, GenericClassDelegateImp<Int>>(delegate)