What Are You Delegating?
Every abstraction is a trade: it removes work by making decisions for you. Those decisions are still being made — just not by you, and not visibly. For each abstraction: what it genuinely handles, what remains yours, and the escape hatch.
An ORMAn HTTP client or SDKA managed database or cloud platformAn identity providerAn LLM or coding agentA web frameworkA library functionA managed message queueA cacheA container runtime and orchestrator
What are you delegating to a library function?
DSAYou write
1items.sort((a, b) => a.score - b.score)2const seen = new Set(ids)The abstraction handles
- ✓A correct, tested, adaptive algorithm chosen for the general case
- ✓Memory layout, cache behaviour, the small-input special cases
- ✓Stability guarantees (if documented) and edge cases (empty, one element,
NaN) - ✓Decades of bug fixes
Still your responsibility
- →Complexity —
O(n log n)is the general bound; whether your case is general is your call - →The escape hatch the library cannot see — small-integer keys sort in linear time; top-K needs a heap, not a sort
- →The comparator — an inconsistent comparator produces silently wrong order
- →Where it runs — a sort inside a loop is the most common accidental quadratic
- →The data structure underneath — a
Setis a hash table; its guarantees and its pathologies are the hash table's
Know your escape hatch
When: The general algorithm is measurably the bottleneck, and your input has structure the library cannot assume.
Drop to: The specific algorithm — counting sort, a heap, a bloom filter, a trie — chosen from the constraints.
This is what the DSA domain is for: not to rewrite the standard library, but to recognise the day its assumptions do not hold.
Go deeper on this one: