# Swift Language Expert

> Use this skill for non-obvious Swift LANGUAGE and standard-library techniques -- features that make code clearer, safer, or faster but that developers routinely miss. Covers pattern matching (if/guard-case, switch over tuples); functions, closures, and key paths (variadics, autoclosures, rethrows); value semantics and custom types (copy-on-write, ~Copyable, callAsFunction, recursive enums, property wrappers); protocols and generics (associated types, opaque some vs existential any, phantom types, hand-rolled type erasure); collections (lazy, RangeSet, InlineArray, sorting); strings and Unicode (grapheme-correct iteration, custom interpolation); concurrency and errors (async/await, task groups, AsyncStream, typed throws, custom global actors, Mutex and the Synchronization framework, and the nonisolated(unsafe)/assumeIsolated/@preconcurrency escape hatches); and debugging and code organization (assertions, dump, enum namespaces, directives). Trigger for "how do I do X in Swift" and idiomatic refactors. Do NOT u

- Skill: `swiftyjourney/swift-language-expert` (Agent Skill, multi-file: 9 files)
- Install (CLI): `npx skillmds@latest add swiftyjourney/swift-language-expert`
- Raw SKILL.md: https://api.skillmd.com/api/skills/swiftyjourney/swift-language-expert/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: SwiftyJourney (https://skillmd.com/u/swiftyjourney)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/swiftyjourney/swift-language-expert

---


# Swift Language Expert

Non-obvious Swift **language and standard-library** techniques. This skill is about the language itself — not UI, not app architecture, not a test framework.

## Agent Behavior Contract

When this skill is active, follow these rules **strictly**:

1. **Language & stdlib only.** SwiftUI → defer to `swiftui-expert`; app architecture / composition / *where* actor isolation goes in a layered app → `ios-architecture-expert`; test-framework syntax (`@Test`/`#expect`, `XCTestCase`), test doubles, async-test determinism → `swift-testing-expert`.
2. **Prefer value types + copy-on-write** for shared data; reach for a class only when you need identity, shared mutable state, or deinit/lifecycle.
3. **Prefer opaque `some` over existential `any`** when a function returns one concrete type; use `any` only for genuinely heterogeneous storage, and know it costs dynamic dispatch + boxing.
4. **Use `lazy` for chained collection transforms** over large sequences to avoid intermediate allocations; eager is fine for small or single-pass work.
5. **Respect Unicode.** Iterate `Character` (grapheme clusters) for user-perceived characters; never index a `String` by `Int` — use `String.Index`.
6. **Prefer pattern matching** (`if`/`guard case`, `switch` with tuples and `where`) over chained `if let` / boolean ladders.
7. **Prefer structured concurrency** (`async let`, `withTaskGroup`) over detached `Task {}` for child work. Where actor isolation belongs in an *architecture* is out of scope — defer to `ios-architecture-expert`.
8. **Gate recent language features** by Swift/toolchain version: `~Copyable`/`borrowing`/`consuming`, typed `throws`, `InlineArray`, primary associated types, `RangeSet`.

---

## Swift Technique Diagnostic Table

| Symptom / goal | Reach for | Deep dive |
|---|---|---|
| Pyramid of nested `if let` / boolean ladders | `guard`/`if case`, optional patterns, `switch` over tuples | `references/pattern-matching-and-control-flow.md` |
| An argument is evaluated even when unused (e.g. `assert`, log) | `@autoclosure` (+ `@escaping` where needed) | `references/functions-closures-keypaths.md` |
| Passing "which property" around as data | key-path expressions (`\.name`), key-path-as-function | `references/functions-closures-keypaths.md` |
| A class used only to share/mutate a value | value type + copy-on-write (`isKnownUniquelyReferenced`) | `references/custom-types.md` |
| A type that must never be copied (handle, lock, token) | `~Copyable` + `consuming`/`borrowing` | `references/custom-types.md` |
| `String`-typed IDs of different kinds get mixed up | phantom types (a generic tag parameter) | `references/protocols-and-generics.md` |
| `any Protocol` everywhere / dynamic-dispatch cost | `some` (opaque) vs `any` (existential); primary associated types | `references/protocols-and-generics.md` |
| `filter` + `map` over a huge collection allocates twice | `.lazy`; `RangeSet`/`DiscontiguousSlice` for non-contiguous selection | `references/collections.md` |
| Splitting/counting a string gives wrong results on emoji/accents | grapheme-cluster iteration, `String.Index`, normalization | `references/strings.md` |
| Hand-rolled pluralization / building strings with `+` | custom `StringInterpolation`, raw strings | `references/strings.md` |
| Fan out concurrent work and collect results | `async let`, `withTaskGroup` / `withThrowingTaskGroup` | `references/concurrency-and-errors.md` |
| Bridge a delegate/callback API to async | `AsyncStream`, `withCheckedContinuation` | `references/concurrency-and-errors.md` |
| `catch` can't enumerate the errors a function throws | typed `throws` | `references/concurrency-and-errors.md` |
| Shared mutable state, but no `await` available (counter, cache, test stub) | `Mutex` + `withLock` from `Synchronization` | `references/concurrency-and-errors.md` |
| Need serialized access off the main thread | a custom `@globalActor` | `references/concurrency-and-errors.md` |
| "Not concurrency-safe" on a global, or a legacy callback you know is on main | `nonisolated(unsafe)` / `MainActor.assumeIsolated` / `@preconcurrency` — narrowest first | `references/concurrency-and-errors.md` |
| Can't store a protocol that has associated types | hand-rolled type eraser (`AnyX` forwarding through closures) | `references/protocols-and-generics.md` |
| Global `let` constants polluting the namespace | caseless `enum` namespace, type subscripts | `references/debugging-and-organization.md` |

---

## Guardrails

- Do not use a `class` where a `struct` (+ copy-on-write if needed) suffices — reach for reference types only for identity/shared-mutable-state/lifecycle
- Do not return `any P` when one concrete type is returned — use `some P`
- Do not index `String` by integer offsets — use `String.Index`; iterate `Character` for user-perceived characters
- Do not chain `if let` ladders where a `guard case`/`switch` reads clearer
- Do not spawn unstructured `Task {}` for child work that should be `async let` / a task group
- Do not solve SwiftUI, app architecture, or testing problems here — defer to the sibling skills
- Do not use bleeding-edge syntax without gating it by Swift/toolchain version

---

## Reference Router

Open the smallest reference that matches the question:

- **Control flow & functions**
  - [pattern-matching-and-control-flow.md](references/pattern-matching-and-control-flow.md) — `if`/`guard case`, `switch` over tuples/ranges, optional patterns, labeled loops
  - [functions-closures-keypaths.md](references/functions-closures-keypaths.md) — variadics, autoclosures, `rethrows`, overloading, key paths
- **Types**
  - [custom-types.md](references/custom-types.md) — value semantics, copy-on-write, `~Copyable`, `callAsFunction`, `Comparable`/literal conformances, recursive enums, property wrappers
  - [protocols-and-generics.md](references/protocols-and-generics.md) — associated types, `Self`, `some` vs `any`, primary associated types, phantom types, constraints, hand-rolled type erasure
- **Data**
  - [collections.md](references/collections.md) — lazy sequences, `RangeSet`/`DiscontiguousSlice`, `ContiguousArray`/`InlineArray`, sorting, `mapValues`
  - [strings.md](references/strings.md) — `String.Index`, grapheme/Unicode handling, normalization, raw strings, custom interpolation
- **Concurrency & errors**
  - [concurrency-and-errors.md](references/concurrency-and-errors.md) — async/await, structured concurrency, `AsyncSequence`/`AsyncStream`, typed `throws`, global actors, `Mutex`, isolation escape hatches
- **Tooling**
  - [debugging-and-organization.md](references/debugging-and-organization.md) — assertions, `dump`, `CustomDebugStringConvertible`, type subscripts, enum namespaces, compiler directives

