1.4 · Generics, <code>some</code>, <code>any</code>

Generics keep the concrete type known to the compiler. Existentials throw it away. Almost every performance and API-design question in this section is a consequence of that one difference.

Mental model. Generic = “the compiler knows the type, you do not need to.” Existential = “nobody knows the type, dispatch through a table.”

Generics vs existentials

Keep the type, or erase it.

  1. Generics vs protocols as types: when do you write <T: P>(T) vs any P? 1.4.1 · L2
    Use generics at API boundaries you control: the compiler keeps the concrete type, specializes the function, and can inline it. Zero existential cost. Use any P…
  2. some View vs any View — what is the difference, and why does SwiftUI use some? 1.4.2 · L3
    some View is an opaque type: one concrete type is chosen by the implementation and hidden from the caller. The compiler still knows it, so it can specialize…
  3. What is the cost of any vs some on a hot path? 1.4.3 · L5
    any: the value may be boxed on the heap, every method call is indirect through a witness table, the caller cannot inline, and the existential container itself…

Opaque types

One hidden concrete type.

  1. What is the difference between some P as a parameter (Swift 5.7) and <T: P>? 1.4.4 · L3
    For a single parameter they are almost identical: some P is an anonymous generic parameter. The differences: You cannot spell the type later — no way to…
  2. What is the difference between some in return position and some in parameter position, historically? 1.4.5 · L8
    Return position (Swift 5.1) is an opaque result type: the function picks one concrete type and hides it. The compiler still uses that exact type, which is why…

Under the hood

What the compiler and runtime actually build.

  1. What is an existential container? What is a witness table? 1.4.6 · L5
    An existential (any P) is stored in a container with three parts: Value buffer — three words inline; larger values are boxed on the heap. Value witness table…
  2. What is generic specialization? When does it not happen? 1.4.7 · L5
    Specialization clones a generic function for a concrete T, replacing witness-table calls with direct calls and enabling inlining. It happens aggressively…

More in Swift language