CONCEPT 01 · FOUNDATIONS
Referential Transparency
"Can I trust this function completely?"
Plain English
A function is referentially transparent if you can replace any call to it with its return value — and the program behaves exactly the same. It means the function has no hidden behavior: no reading from globals, no writing to databases, no randomness, no time-dependency. What goes in determines what comes out, always.
Analogy
Think of a calculator. You press 3 × 4 and always get 12. You can replace the expression "3 × 4" with 12 anywhere in your math homework and nothing changes. But a vending machine is not referentially transparent — pressing the button twice might return different results depending on stock, payment state, and timing.
You already know this
Math.max(3, 5) → always 5String.slice(), Array.map() — same input, same outputPure utility functions you already write (formatters, validators)SQL expressions like UPPER("hello") → always "HELLO"
Interactive Demo
Click [SUBSTITUTE] to evaluate step by step
Watch how a pure expression simplifies like algebra. Same input → always same result.
abs(abs(-5)) → Pure / Always Substitutable
Code Example
JavaScript
// NOT referentially transparent — result changes each call
let count = 0;
function nextId() {
return ++count; // depends on external mutable state
}
nextId(); // → 1
nextId(); // → 2 (different result, same call!)
// NOT referentially transparent — depends on time
function greet() {
const hour = new Date().getHours();
return hour < 12 ? 'Good morning' : 'Good afternoon';
}
// REFERENTIALLY TRANSPARENT — same input, same output, always
function add(a, b) {
return a + b; // no side effects, no external state
}
add(3, 4); // → 7, today, tomorrow, in any order, forever
function formatPrice(cents) {
return '$' + (cents / 100).toFixed(2);
}
formatPrice(1099); // → '$10.99', alwaysApply when
▸Writing utility functions (formatters, validators, calculators) — make them RT so they're trivially testable
▸Refactoring: if a function is RT, you can safely inline it, extract it, or call it any number of times
▸When debugging: RT functions eliminate themselves as suspects — the bug must be elsewhere
▸In critical business logic (pricing, billing, scoring) — RT means no surprises in production
Check Your Understanding
Which of these functions is referentially transparent?