Search code examples
oopfunctional-programmingsoftware-design

What is most important philosophy/concept of functional programming compared to object-oriented programming?


For me, OOP was all about Autonomy which is achieved by two main concepts: (1) Encapsulation and (2) Message Passing.

  • Concepts (like subtyping, late binding, multiple dispatch, interfaces and implementations, prototype, access modifier, constructor and destructor, ...) are mechanisms to support encapsulation and message passing.
  • Concepts (like responsibility, open-close principle, dependency injection, creation-usage separation, ...) are disciplines to design good objects.

And now I'm learning FP and want to figure out:

  • FP is all about [MASK] which is achieved by main concept(s): (1) Referential Transparency, and [MASK]*
  • Is concepts (like immutability, closure and higher-order functions, continuations, algebraic data types, categorical typeclasses or traits, ...) are mechanisms to support those main concepts?
  • And what are important design disciplines for good functions? I think data-behavior separation would be one of them but not sure...

Can you share your insights on FP paradigm? Thank you!


Solution

  • Most of the characteristics listed for OOP in the OP apply to FP as well - perhaps with the exception of inheritance.

    But even so, some functional-first languages (e.g. F#) support inheritance, and some object-oriented languages don't have inheritance.

    There's no single, accepted definition of exactly what constitutes OOP, and the same is true for FP. I discuss this in my article Functional architecture: a definition, where I also posit that the defining characteristic of FP is referential transparency.

    Many of the other well-known traits of FP (immutability, higher-order functions, closures, etc.) stem directly or indirectly from the emphasis on referential transparency. Some typical FP trappings like monads could also be said to originate from referential transparency, but mostly in the sense that they are successful solutions to some of the problems that arise from referential transparency (e.g. hos to maintain state while performing a complex calculation, which can be addressed by the State monad).

    Still, there are disparate takes on FP. Just compare Clojure to Haskell. These languages are both, by their communities, considered functional, and still, they are very different. Many of the characteristics suggested in the OP (type classes, algebraic data types) are typical for Haskell, while not really a thing in Clojure, because Clojure is dynamically typed.

    Clojure, on the other hand, emphasises typical Lisp-like properties like homoiconicity and macros, and its community embrace dynamic typing. (Read this, however, with the caveat that I know Haskell much better than I know Clojure.)