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 const and 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.