What's functional programming all about? (2017)
Core definitions of functional programming
- Disagreement on what FP “really” is: data-flow vs control-flow; separation of data and methods; expression-orientation; “no side effects”; or “programs as formulas/expressions” rather than procedures.
- Some argue FP is basically “practical λ-calculus” or “programming with referentially transparent functions.”
- Others say these definitions are fuzzy and paradigms are more marketing clusters than precise categories.
Immutability, side effects, and reasoning
- Many see immutability and minimized global state as the practical core: easier reasoning, fewer ordering bugs, and simpler refactoring.
- Pure functions enable equational reasoning: same input → same output, no hidden state.
- Some argue you can approximate this in C/C++/Java with
constand immutable collections, but FP languages enforce it more strongly.
FP vs OO / imperative
- FP emphasizes functions and value transformations; OOP emphasizes objects and encapsulated mutable state.
- “Expression problem” is cited: FP makes it easy to add new operations, harder to add new data variants; OOP is the reverse.
- Many note that modern mainstream languages are multi-paradigm; strict boundaries are less relevant in practice.
Benefits and positive experiences
- Reported wins: easier testing, parallelism (because less shared mutable state), and clearer data flow.
- Some describe large Clojure/FP-heavy codebases as significantly easier to reason about and refactor.
- Concepts from FP (higher-order functions, closures, immutable data) are widely borrowed in non-FP languages.
Critiques and limitations
- Several find FP code harder to read and write; chains of nested calls or deep combinator usage feel like “inside-out messes.”
- Claims that FP yields fewer defects are challenged; some say empirical evidence doesn’t support superiority.
- FP can struggle with complex real-world state, circular dependencies, performance-sensitive code, and ergonomics (e.g., Haskell’s steep learning curve, complex types).
Types, monads, async, and laziness
- Debate over whether FP’s advantages mostly come from rich static types, not from purity per se.
- Monads are discussed as pervasive in disguise (e.g., async/await and Promises behaving “like monads,” though not law-abiding in all edge cases).
- Laziness and expression-orientation (no strict execution order, infinite streams) are noted as distinctive but not always crucial for day-to-day work.
Pragmatism and mixed styles
- Many advocate “functional core, imperative shell”: keep most code pure and immutable, isolate side effects at the edges.
- Lisp/Clojure-style pragmatism is praised: use FP ideas where they help, avoid purity zealotry, blend tools as needed.