Choosing between some, any, and generics
Pick generics for homogeneous static typing, some P to hide a fixed concrete type, and any P for heterogeneous polymorphism.
When to use which?
Rule of thumb:
- Generics: same concrete type per call; best compile-time checks & performance.
- some P: hide the concrete return type, fixed per function.
- any P: mix conformers (heterogeneous), dynamic dispatch.
Generics: homogeneous
Generics are ideal for homogeneous data and optimization (static dispatch, inlining).
protocol Shape { func area() -> Double }
struct Circle: Shape { let r: Double; func area() -> Double { .pi * r * r } }
struct Square: Shape { let s: Double; func area() -> Double { s * s } }
// Generic: one concrete Shape type per call site (homogeneous)
func totalAreaGeneric<S: Sequence, T: Shape>(_ xs: S) -> Double where S.Element == T {
xs.reduce(0) { $0 + $1.area() }
}
print(totalAreaGeneric([Circle(r:1), Circle(r:2)])) // OK
// totalAreaGeneric([Circle(r:1), Square(s:2)]) // ❌ different typesAll lessons in this course
- some P (opaque result types): hiding concrete types
- any P (existential): trade-offs & dynamic dispatch
- Choosing between some, any, and generics