CONCEPT Cited by 1 source
Three-valued logic¶
What it is¶
Three-valued logic extends classical boolean logic with a third
state — variously called null, unknown, or indeterminate —
representing "I don't have enough information to decide yet." An
expression evaluates to one of {true, false, null}.
The Kleene / SQL truth tables under three-valued logic:
and |
true |
false |
null |
|---|---|---|---|
true |
true |
false |
null |
false |
false |
false |
false |
null |
null |
false |
null |
or |
true |
false |
null |
|---|---|---|---|
true |
true |
true |
true |
false |
true |
false |
null |
null |
true |
null |
null |
Key short-circuit properties:
true or null = true(enough info to decide)false and null = false(enough info to decide)null and null = null,null or null = null(still can't decide)
Why it matters¶
- Short-circuit control loops. If an outer expression already
decides
trueorfalsedespite unresolved subexpressions, the system can stop loading the missing data and return — this is the optimization Figma reports "more than halved the total execution time of our permissions evaluation" (Source: sources/2026-04-21-figma-how-we-built-a-custom-permissions-dsl). - Incremental computation. Load → evaluate → still-unknown? load more → evaluate → repeat until determined, leaving load work undone when possible. See patterns/progressive-data-loading.
- Graceful missing-data handling. Distinguishes "I looked and it's false" from "I haven't looked yet."
Authorization application (Figma)¶
A permissions engine evaluates an ExpressionDef against a loaded
data map. Fields that have not yet been fetched are marked
PENDING_LOAD:
data = {
team: { permission: "secret" },
file: PENDING_LOAD,
project: PENDING_LOAD,
}
expr = {
and: [
["file.id", "<>", null], // ? (unknown)
["team.permission", "=", "open"], // false
["project.deleted_at", "<>", null], // ? (unknown)
]
}
team.permission = "open" is false. In an and, false short-circuits
the whole expression to false — Figma can exit without loading
file or project. Contrast with the same data under an or:
false or ? or ? is still unknown; must keep loading.
SQL precedent¶
SQL uses three-valued logic for NULL: NULL = NULL → NULL
(not true), NULL AND false → false, NULL OR true →
true. The semantics are identical; the engineering application
(making NULL handling sound vs. enabling short-circuit data loading)
differs.
Caveats¶
- Static-analysis gotcha.
[field, "=", {ref: otherField}]evaluates totruewhen both sides arenullin some engines (Figma's included), which is almost never the intended semantic. Figma's CI linter flags this unless a sibling[field, "<>", null]exists under anand. See patterns/policy-static-analysis-in-ci. - Engine complexity. Implementing three-valued truth tables correctly across multiple evaluators (Figma has Ruby, TypeScript, Go) requires a shared test suite.
- Not free. Each evaluation pass over a partially-loaded data set costs CPU; the savings come from avoided database round trips, not from less in-memory work.
Seen in¶
- sources/2026-04-21-figma-how-we-built-a-custom-permissions-dsl
— canonical application to authorization:
null/ indeterminate as a first-class evaluator return value, partitioned load plan,>2×end-to-end evaluation speedup.