some P (opaque result types): hiding concrete types
Return some P to hide the concrete return type while promising it conforms to P ; callers gain static type performance without exposing implementation.
some P (opaque result types): hiding concrete types is a free Swift Academy lesson on CoddyKit — lesson 1 of 3. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Swift Academy learning path, one of 3 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why opaque result types?
Opaque result types use some P to hide a concrete type behind a protocol. The concrete type is fixed for that function, but callers only see the protocol surface.
- Encapsulation without losing static performance
- Great for factories and DSL-like APIs
Basic opaque factory
makeUnitCircle() returns some Shape. Callers can call area(), but cannot rely on the concrete type.
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 }
}
// Opaque factory: callers know it's a Shape, not which one
func makeUnitCircle() -> some Shape {
Circle(r: 1.0) // concrete type is hidden
}
let sh = makeUnitCircle()
print(String(format: "%.2f", sh.area())) // 3.14Fixed per function
The hidden type is fixed per function. Another function returning some Shape may hide a different concrete type.
// Each function using "some Shape" chooses one hidden concrete type.
// Within the same function, it must always be the same concrete type.
func makeSquare(side: Double) -> some Shape {
Square(s: side) // fixed to Square for this function
}
let a = makeUnitCircle()
let b = makeUnitCircle()
print(a.area() == b.area()) // true for two unit circles
let q = makeSquare(side: 2)
print(q.area()) // 4.0One hidden type only
Rule: a function with an opaque return must return the same concrete type along every path. Different branches → compile error.
// ❌ This would NOT compile, because different branches return different concrete types:
// func makeShape(flag: Bool) -> some Shape {
// if flag {
// return Circle(r: 1)
// } else {
// return Square(s: 1) // error: underlying type must be the same
// }
// }
// Rule: an opaque-returning function must always produce the same concrete type.Opaque with generics
Opaque returns compose with generics. The caller sees a Shape, while you keep the Scaled<Circle> implementation private.
// A generic decorator that also conforms to Shape
struct Scaled<S: Shape>: Shape {
let base: S
let k: Double
func area() -> Double { base.area() * k * k }
}
// Factory still hides the concrete generic type
func makeScaledUnitCircle(k: Double) -> some Shape {
Scaled(base: Circle(r: 1.0), k: k)
}
let s1 = makeScaledUnitCircle(k: 2)
print(s1.area()) // 4 * πWhen to choose opaque
Use opaque types when:
- You want to hide implementation but keep static typing.
- APIs should return a protocol view (e.g.,
Shape) without exposing concrete types. - You build pipelines/DSLs that chain builders while staying generic.
(You will compare with existentials in the next lesson.)
Opaque result definition
Quick check: What does some P promise?
Recap
Recap: Opaque result types (some P) hide concrete types yet keep static dispatch. The underlying type is fixed per function; use them for clean, fast, encapsulated APIs.
Frequently asked questions
Is the “some P (opaque result types): hiding concrete types” lesson free?
Yes — the full text of “some P (opaque result types): hiding concrete types” is free to read here on the web, and the Swift Academy course includes 3 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Swift Academy course, upgrade to CoddyKit PRO.
What will I learn in “some P (opaque result types): hiding concrete types”?
Return some P to hide the concrete return type while promising it conforms to P ; callers gain static type performance without exposing implementation. You practise Swift Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Swift Academy?
No prior experience is required. Swift Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 3, so you can start here or from the beginning and move at your own pace.
How long does the “some P (opaque result types): hiding concrete types” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Swift Academy lesson?
Yes. Every Swift Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All 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