Ability-guarantee tradeoff
- title
- Ability-guarantee tradeoff
- type
- concept
- summary
- The more a language, format or tool can do, the fewer things it guarantees: Hillel Wayne's name for the tradeoff behind safe subsets
- tags
- logic, language-design, formal-methods
- sources
- crash-course-predicate-logic
- created
- 2026-09-14
- updated
- 2026-09-14
Hillel Wayne states it in Logic for Programmers: the more things a language, format or tool is able to do, the fewer things it guarantees. He introduces it in the chapter on predicate logic, summarized at predicate-logic-crash-course crash-course-predicate-logic, and says the book comes back to it in almost every chapter.
Where it comes from
The argument starts from quantifiers. some x in S: P(x) gets easier to satisfy as S grows, because there are more candidates, and all x in S: P(x) gets easier as S shrinks. So if S1 is a subset of S2, you should expect some predicate that holds for every element of S1 and fails for some element of S2. That predicate is what S1 guarantees. Let the set be "everything this system can express or do", and restricting it is how a guarantee gets bought.
Wayne's three examples each pair a set with a superset:
- ASCII is a subset of Unicode. Every ASCII character fits in one byte, so the string
ABCis three bytes on sight. In Unicode the same-looking string can be six bytes if the letters are Cyrillic. - What a program can do with read-only access to a file is a subset of what it can do with full access. Read-only guarantees the contents stay unchanged, while with full access any buggy program can overwrite the data.
- Formulas built only from Booleans, AND, OR and NOT are a subset of all logical formulas, and every one of them can be turned into a truth table.
some x in Nat: OddPerfectNumber(x)can't, and mathematicians still don't know whether it is true.
The capability on the other side is always wanted by someone. Emoji need Unicode, updating data needs write access, and most interesting predicates need quantifiers. The tradeoff is a decision about which side a particular job needs, and it doesn't make the smaller set better in general.
Why not call it power
Wayne notes that "ability" is sometimes called power, as in the rule of least power (prefer the least powerful language that solves the task), and that he has also seen "guarantees" called power. A "power-power tradeoff" communicates nothing, so the book avoids the word altogether.
Logic itself is an instance. First-order logic forbids putting predicates in sets or passing them to other predicates, and in his description higher-order logics have more abilities and fewer guarantees. Propositional logic, with no quantifiers at all, sits below both and is the level at which truth tables always work.
The same shape elsewhere in the vault
The pages below don't use Wayne's term; reading them through it is this page's framing.
Memory-safe systems languages buy their guarantees by shrinking the set of programs a compiler accepts. memory-safety-absolutists describes Rust as refusing any program that may introduce memory-safety issues, accepting that it will sometimes reject one that was fine, and offering unsafe as the way back into the larger set. cobaltc writes that boundary into its specification. Safe code carries an enumerated list of guarantees. An unsafe block or a foreign call regains abilities, the specification stops promising what it can no longer check, and a safe wrapper must re-establish the missing invariants before control returns to safe code.
Databases trade along a different axis. stop-calling-databases-cp-or-ap points out that snapshot isolation and MVCC are non-linearizable on purpose, since enforcing linearizability would reduce the concurrency the database can offer. ZooKeeper's default reads skip linearizability for speed, and a sync call before a read buys it back for that one read. What is given up there is throughput or latency, and the guarantee is how recent a read must be.