What is Swift's type system — protocols with associated types and existentials?

Answer

Swift's type system includes protocols with associated types (PATs), which are more powerful but less flexible than simple protocols. Understanding them is crucial for advanced Swift. Protocol with associated type: protocol Collection { associatedtype Element // Generic placeholder associatedtype Iterator: IteratorProtocol associatedtype Index: Comparable func makeIterator() -> Iterator subscript(position: Index) -> Element { get } } // Can't use directly as type: // var c: Collection // ERROR -- "Protocol 'Collection' can only be used as a generic constraint". The problem — existential types (any): before Swift 5.7, you couldn't use PATs as types. Since 5.7, use any: var sequences: [any Sequence<Int>] = [] // Heterogeneous sequences of Int var collections: [any Collection] = [] // Heterogeneous but runtime type erasure. Primary associated types (Swift 5.7): protocol Sequence<Element> { // Element is primary associatedtype Element }. Opaque types (some) — concrete but hidden: func makeNumbers() -> some Collection<Int> { return [1, 2, 3] // Specific type hidden but concrete at compile time } // SwiftUI: var body: some View { /* specific type */ }. Type erasure (manual): wrap a PAT in a concrete struct: struct AnySequence<Element>: Sequence { private let _makeIterator: () -> AnyIterator<Element> init<S: Sequence>(_ sequence: S) where S.Element == Element { self._makeIterator = { AnyIterator(sequence.makeIterator()) } } func makeIterator() -> AnyIterator<Element> { _makeIterator() } }. any vs some: some = one specific type (opaque, compile-time); any = any conforming type (existential, runtime type erasure). Use some for performance; any when you need heterogeneity.