Purity and side effects
A pure function depends only on its inputs and produces no side effects:
// pure
const pure = (a, b) => a + b;
// impure
let cache = [];
const impure = (a) => { cache.push(a); return a; };
Pure functions are deterministic and easy to test. Real programs need side effects (I/O, state), so isolate them at the edges and keep the core pure. This makes reasoning and testing tractable.
Effectives and monads
Patterns like Maybe/Either handle missing values without null checks:
const maybe = (fn) => x => x == null ? null : fn(x);
const safeDiv = maybe(b => a => a / b);
console.log(safeDiv(0)(5)); // null (avoid division by zero)
While full monadic style is advanced, the idea of wrapping values that may fail (Option/Either) and composing over them is a powerful way to keep null handling out of your core logic.