LeadershipNot yet confirmed elsewhere1 publisher3 min readPublished
Expressiveness Is A Cost: The Tradeoff Behind Every "Make It More Flexible" Request
Hillel Wayne names a design law engineering leaders keep paying for by accident: the more your system can represent, the fewer guarantees you can make about it.
The Board Room · Leadership desk
What happened
- An essay titled "The Capability-Tractability Tradeoff" was published in Hillel Wayne's newsletter on buttondown.com.
- The essay's subtitle states: "The more you can say, the less you can say about what you can say."
- The stated tradeoff: the more things your system can represent, the less you can say about the things that are represented.
- The stated reason for the tradeoff: the more things your system can represent, the fewer things they all have in common, and the more likely any assertion about that set will have a counterexample.
- If you store strings as ASCII you cannot represent a string containing the symbols for-all, there-exists and a hedgehog emoji; if you store strings as Unicode, the string's length is not well defined. Unicode is described as more capable, ASCII as more tractable.
Why it matters
Hillel Wayne's newsletter puts a name to a failure mode most engineering organisations experience as a run of unrelated incidents: the capability-tractability tradeoff, which he summarises as "the more you can say, the less you can say about what you can say" [8] [9]. The operator's version is that expressiveness is not a free feature on a roadmap; it is paid for in guarantees, and the invoice arrives later than the request.
The mechanism is not subtle. The more things a system can represent, the less you can say about the things represented [10], because the more things it can represent, the fewer properties they all share, and the more likely any assertion about the set has a counterexample [11]. Store strings as ASCII and you cannot represent "for all, there exists, hedgehog"; store them as Unicode and length is no longer well defined [12].
The canonical case is the computability hierarchy. Turing machines are the most powerful realizable model under the Church-Turing claim [1], and the halting theorem says no algorithm decides whether an arbitrary Turing machine halts on an arbitrary input [2]. A pushdown automaton cannot compute every decision problem but is guaranteed to return yes or no on every input [3]; a deterministic finite automaton is more restricted still and more tractable again [4]. Nobody sells that ladder as a feature request, but every "let users express arbitrary rules" ticket climbs it.
The direction of the tradeoff is what leaders get wrong. Rust's type system is sound, so a compiled Rust program will not have type errors [13], and all sound type systems are incomplete, meaning valid programs get rejected [14]. Python will let you type anything as anything and stay quiet until you ask a datetime for its employee_id [15], so Python is more capable and less tractable than Rust on typing [16]. Reverse the property and the ranking flips: Python has no concept of a memory address or a memory bug, so Rust is the more capable and less tractable system for memory manipulation [5] [6]. Wayne's conclusion is that this is closer to a lattice than a spectrum [7], which means "more flexible" is not a well-formed request until someone names the property being traded away [25].
He does not treat tractability as automatically dominant. Once a system is capable enough to cover its use case, extra capability buys nothing [26], but requirements change and a system can turn out not to be capable enough [27], and backwards compatibility makes adding features easier than removing them [17]. That asymmetry is the governance problem: capability accretes by default, so the tradeoff only ever gets paid in one direction unless someone spends political capital to reverse it [19]. Making a system more capable can break tractability outright [18].
The same pattern shows up in choices your teams make monthly: what fits in JSON versus YAML versus XML versus a SQL database [20], SAT solving being much easier than SMT or constraint solving while encoding fewer problems [21], and static analysis being far easier in a language without macros, introspection, or metaprogramming [22]. Even in mathematics, the complex numbers are a superset of the reals, and the reals are totally ordered while the complex numbers are not [23].
Two things to watch in your own review meetings. First, whether any request for flexibility arrives with the invariant it destroys written down; a free-form column, an "any" type, or a user-supplied rule engine is a decision to stop being able to check something. Second, whether the guarantees you already sell to customers or auditors depend on a property that the next expressiveness increment quietly removes. Note that the essay making this argument also advertises the author's paid TLA+ workshop and a spec review [24]; the tradeoff stands on its own examples.
Clarity's read
What the record supports and how the coverage leans. The claims behind it follow.
Reality
- Evidence58
- Adoption
- Insufficient
- Hype gap+5
- Incentives45
- Confidence55
Claim ledger
Ranked by verification strength, evidence, and original report placement.
- [1]
The Church-Turing claim holds that a Turing machine is the most powerful kind of automata: if a decision problem cannot be computed by a Turing machine, it cannot be solved by any realizable computational system.
- [2]
The halting theorem says there is no algorithm which can determine if an arbitrary Turing machine halts on an arbitrary input.
- [3]
A pushdown automaton is a weaker system that cannot compute every decision problem, but is always guaranteed to return yes or no for every input: more tractable, less capable.
- [4]
At the bottom of the hierarchy is the deterministic finite automaton, which can only compute a very restricted set of problems and is even more tractable than a pushdown automaton.
- [5]
Python has no concept of a memory address, no pointer to one, and no concept of a memory bug.
- [6]
Rust is more capable and less tractable than Python with respect to memory manipulation: it can represent a wider range of memory-manipulating programs, but there is no guarantee that any given Rust program is memory-safe.
- [7]
Capability and tractability must be discussed with respect to a property or class of representations; the structure is closer to a lattice than a spectrum.
- [8]
An essay titled "The Capability-Tractability Tradeoff" was published in Hillel Wayne's newsletter on buttondown.com.
- [9]
The essay's subtitle states: "The more you can say, the less you can say about what you can say."
- [10]
The stated tradeoff: the more things your system can represent, the less you can say about the things that are represented.
- [11]
The stated reason for the tradeoff: the more things your system can represent, the fewer things they all have in common, and the more likely any assertion about that set will have a counterexample.
- [12]
If you store strings as ASCII you cannot represent a string containing the symbols for-all, there-exists and a hedgehog emoji; if you store strings as Unicode, the string's length is not well defined. Unicode is described as more capable, ASCII as more tractable.
- [13]
Rust's type system is sound: a compiled Rust program is guaranteed not to have type errors.
- [14]
All sound type systems are also incomplete, meaning there are valid programs that the Rust compiler might reject.
- [15]
In Python you can type anything as anything and it will not complain until you try to get the employee_id field from a datetime.
- [16]
Python is more capable and less tractable than Rust with respect to typing: it can represent a wider range of well-typed programs, but there is no guarantee that any given Python program is well-typed.
- [17]
Backwards compatibility makes it easier to add features, which trades tractability for capability, than to remove features, which goes the other way.
- [18]
The essay notes that if you make a system more capable, you might break tractability.
- [19]
Given that adding capability is easier than removing it, capability accumulates by default and tractability is spent in one direction unless a decision is taken to reverse it.
- [20]
Listed as an example of the tradeoff: the data you can encode in JSON versus YAML versus XML versus a SQL database.
- [21]
SAT solving is much easier than SMT or constraint solving, but also encodes fewer problems.
- [22]
Static analysis is a lot easier when your language does not have macros, introspection, or metaprogramming.
- [23]
In mathematics, complex numbers are a superset of the reals, but the reals are totally ordered and the complex numbers are not.
- [24]
The same newsletter issue advertises a TLA+ workshop in May with a 15% discount code and includes a spec review with purchase.
- [25]
Because the ranking of two systems by capability reverses depending on which property is chosen, a request to make a system "more flexible" is not well defined until the property being given up is named.
- [26]
The essay argues tractability seems more important in that once you have enough capability in your system to cover your use case, you do not need more of it.
- [27]
A stated counter-consideration: requirements change, and your system might not be capable enough to handle the change.
Sources
1 independent publisher whose own reporting we read for this story.
- capability-tractability tradeoff
buttondown.com
1 article · August 18, 2026
Topics and entities
Follow any of these and your For You feed starts watching them — no settings page required.