What is the difference between some in return position and some in parameter position, historically?

1.4.5 · L8 · Learning

Predict first

Does this compile?

func make() -> some Equatable {
    if Bool.random() { return 1 }
    return "one"
}
  • Yes
  • No

Mental model. Return-position some hides a fixed type from the caller. Parameter-position some introduces a fresh generic the caller chooses.

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 SwiftUI’s typed view tree works and why you cannot return Text in one branch and Image in another.

Parameter position (Swift 5.7) is sugar for an anonymous generic parameter: the caller chooses the type, and the function can use it generically.

Same keyword, opposite direction of information flow. That is the whole trick.

An opaque return type is still one concrete type chosen by the function. Returning Int on one path and String on another is an error.

Common traps

  • “Opaque means existential.” It is the opposite: opaque keeps the concrete type known to the compiler; existential erases it.
  • Returning different types from branches with some. They must unify. Use @ViewBuilder (which wraps them in _ConditionalContent) or a common concrete wrapper.

They might follow up with

  • Can a caller of a some-returning function see the type? No — not even with reflection, by design.
  • Can you store a some result in a property? Yes, but the property's type must also be written as some P in a type context that supports it (or the concrete type must be inferred in a declaration).

Related questions

  • 1.4.2 some View vs any View — what is the difference, and why does SwiftUI use some?
  • 1.4.4 What is the difference between some P as a parameter (Swift 5.7) and <T: P>?

← What is the difference between some P as a parameter (Swift 5.7) and…   What is an existential container? What is a witness table? →