Functional Programming Self-Affirmations
Value of the article and repetition of “old” FP ideas
- Some see the post as just rehashing well-known FP concepts better covered in books and established blogs.
- Others argue many newer developers never saw the originals; re‑surfacing these ideas in compact form is useful and accelerates learning.
- Several commenters explicitly praise list-style summaries of core FP principles with links for deeper dives.
Learning resources and FP concepts referenced
- Recommended learning materials include Haskell-oriented books and classic posts on:
- “Parse, don’t validate”
- “Make illegal states unrepresentable”
- “Errors as values”
- “Functional core, imperative shell”
- Smart constructors
Applying these ideas outside “pure” FP
- One camp claims most principles can be implemented in mainstream imperative/OOP languages using: immutability, encapsulation, ADTs / sum types (or approximations), generics, wrappers, builders, and disciplined code review.
- Skeptics argue some patterns rely heavily on FP features (type inference, monads, do-notation, expression orientation) and become awkward or fragile without syntactic and type-system support.
Errors as values vs exceptions
- Strong support for “errors as values” in languages like Rust, Go, Zig, Odin; Rust’s
Result,?, and#[must_use]are cited as good ergonomics. - Concerns: returning error values can be silently ignored in imperative languages; exceptions better support “let it crash” behavior.
- Others respond that compilers, annotations, or static analysis can enforce use, and that exceptions vs values is largely a presentation/ergonomics trade-off.
“Make illegal states unrepresentable” – benefits and limits
- Advocates: encoding invariants in types reduces runtime checks, simplifies reasoning, and pushes complexity to compile time.
- Critics: in complex or fast-changing domains (regulation-heavy, finance, configuration with many interdependent options) exhaustive type modeling can explode combinatorially and be expensive to maintain.
- Counterpoint: if you truly have exponentially many meaningful states, the domain is inherently complex; enums/ADTs can be factored rather than listing all combinations, but there’s tension between strict modeling and evolvability.
Functional core, imperative shell and GUI/state
- Widely liked for testability and limiting I/O and concurrency to boundaries.
- Some note difficulties composing “pure core + impure shell” in GUI-style systems and large apps; global state stores (e.g., Redux-like) solve some issues but create others (hidden constraints, database-like complexity).
OOP, FP, and smart constructors
- Several commenters stress that many “FP” ideas (smart constructors, invariants in constructors, sum types, visitor/Church encodings) are not exclusive to FP and can be emulated in OOP languages.
- Debate continues over whether FP or OOP provides better tools for extensibility, live environments, and large-scale maintainability.