851

I've been mainly exposed to OO programming so far and am looking forward to learning a functional language. My questions are:

  • When do you choose functional programming over object-oriented?
  • What are the typical problem definitions where functional programming is a better choice?
Chris
  • 1,533
  • 2
  • 17
  • 33
Olivier Lalonde
  • 19,423
  • 28
  • 76
  • 91
  • Duplicate: http://stackoverflow.com/questions/552336/oop-vs-functional-programming-vs-procedural – gnovice Jan 16 '10 at 22:23
  • this is relevant http://programmers.stackexchange.com/questions/9730/functional-programming-vs-oop – kirill_igum Sep 11 '13 at 02:14
  • 1
    similar question cs.se also closed [what is example where functional programming gives better results than imperative style](http://cs.stackexchange.com/questions/4852/). conventional wisdom seems to be that one is not superior to the other, or they are not comparable on simple criteria, or that they are used for different purposes... functional programming has more scientific/academic origins & uses and is less common in industry, so the question also sets up an "industry vs academia" unresolvable pov/conflict. one classic ref that shows OOP sytle in functional programming, SICP book/MIT – vzn Apr 27 '14 at 15:19
  • "_OO makes code understandable by encapsulating moving parts. FP makes code understandable by minimizing moving parts._" --Micheal Feathers, 2010 – jaco0646 Mar 17 '20 at 00:19

4 Answers4

1300

When do you choose functional programming over object oriented?

When you anticipate a different kind of software evolution:

  • Object-oriented languages are good when you have a fixed set of operations on things, and as your code evolves, you primarily add new things. This can be accomplished by adding new classes which implement existing methods, and the existing classes are left alone.

  • Functional languages are good when you have a fixed set of things, and as your code evolves, you primarily add new operations on existing things. This can be accomplished by adding new functions which compute with existing data types, and the existing functions are left alone.

When evolution goes the wrong way, you have problems:

  • Adding a new operation to an object-oriented program may require editing many class definitions to add a new method.

  • Adding a new kind of thing to a functional program may require editing many function definitions to add a new case.

This problem has been well known for many years; in 1998, Phil Wadler dubbed it the "expression problem". Although some researchers think that the expression problem can be addressed with such language features as mixins, a widely accepted solution has yet to hit the mainstream.

What are the typical problem definitions where functional programming is a better choice?

Functional languages excel at manipulating symbolic data in tree form. A favorite example is compilers, where source and intermediate languages change seldom (mostly the same things), but compiler writers are always adding new translations and code improvements or optimizations (new operations on things). Compilation and translation more generally are "killer apps" for functional languages.

ento
  • 5,801
  • 6
  • 51
  • 69
Norman Ramsey
  • 198,648
  • 61
  • 360
  • 533
  • 138
    There is some serious zen behind this answer. I think it illuminates the fact that certain OOP design patterns (Visitor) are actually hacks which attempt to overcome the problem of adding new operations. – Jacobs Data Solutions Mar 26 '13 at 16:08
  • 66
    In JavaScript, you can have all of the things. – Erik Reppen Nov 15 '13 at 17:38
  • 69
    @ErikReppen at which point the question arises, when do you choose to use the functional features, and when do you choose to use the object-oriented features? – Norman Ramsey Nov 23 '13 at 00:38
  • 7
    @NormanRamsey It's not at all uncommon to mix it up in JS and first-class functions are tied to a lot of JS OOP-related features. JS's array sorting takes functions as an arg which can produce some powerful data structures. Closures + a passed function is used to keep jquery objects very lightweight memory-speaking since most methods are just references. Etc... – Erik Reppen Nov 23 '13 at 00:55
  • 11
    @NormanRamsey: Very good answer, along the lines of SICP. According to this classification, functional and procedural programming are grouped together on the opposite side of object-oriented programming. This could explain the boom of OOP during the late 1980-ies early 1990-ies: when GUIs became mainstream OOP proved to be a good approach for modeling them because you normally have a fixed set of operations (paint, open, close, resize) and a growing number of widgets. Of course, this does not mean that OOP is better than procedural for any application, as you illustrated. – Giorgio Jan 09 '15 at 17:54
  • 1
    "In functional code, the output value of a function depends only on the arguments that are input to the function, so calling a function f twice with the same value for an argument x will produce the same result f(x) each time. Eliminating side effects, i.e. changes in state that do not depend on the function inputs, can make it much easier to understand and predict the behavior of a program, which is one of the key motivations for the development of functional programming." - wikepedia .... You didn't even address this concept. This is a terrible answer. – bigcodeszzer Apr 17 '16 at 19:48
  • @bigcodeszzer not at all. "Program to interfaces" is a common OOP admonition, yes? It's not uncommon to have *many* classes that implement the same interface. If the interface needs to change, one could a) change it directly, requiring something to be done with all of the classes that currently implement it, or b) migrate it to a new version, requiring all of the implementing classes to also migrate (eventually) to a new version that supports the new interface. All because someone decided to add one new method to an existing interface. – Erick G. Hagstrom Jul 05 '16 at 17:36
  • @ErickG.Hagstrom Unless there is a significant performance advantage, the notion of having to make multiple edits for a single change, in my opinion, is indicative of poor design. If this is a result of using an interface, I would say the technique doesn't fit the situation, or is being implemented incorrectly. – bigcodeszzer Jul 06 '16 at 22:44
  • 2
    @bigcodeszzer "poor design", perhaps, but of the language, not the application. Here is an interesting discussion of this issue, commonly called the "Expression Problem", and how it can be solved using language features that are commonly absent from both OO and Functional languages but are present in hybrids like Closure. http://eli.thegreenplace.net/2016/the-expression-problem-and-its-solutions/ – Erick G. Hagstrom Jul 07 '16 at 14:05
191

You don't necessarily have to choose between the two paradigms. You can write software with an OO architecture using many functional concepts. FP and OOP are orthogonal in nature.

Take for example C#. You could say it's mostly OOP, but there are many FP concepts and constructs. If you consider Linq, the most important constructs that permit Linq to exist are functional in nature: lambda expressions.

Another example, F#. You could say it's mostly FP, but there are many OOP concepts and constructs available. You can define classes, abstract classes, interfaces, deal with inheritance. You can even use mutability when it makes your code clearer or when it dramatically increases performance.

Many modern languages are multi-paradigm.

Recommended readings

As I'm in the same boat (OOP background, learning FP), I'd suggest you some readings I've really appreciated:

Community
  • 1
  • 1
Bruno Reis
  • 37,201
  • 11
  • 119
  • 156
  • 1
    Not forgetting you can mix F# and C# code together so you can leverage the best of each – Paolo Jan 16 '10 at 21:44
  • 1
    Your answer is a great example of the power of .Net. It shows it is able to leverage the powers of both paradigms. – Dykam Jan 16 '10 at 21:53
  • 5
    Heh, sorry if I started some flaming. I didn't mean to say other platforms are less powerfull, just that .NET doesn't only support OOP. For example it has tail call optimization. – Dykam Jan 16 '10 at 22:26
  • Rank-N types in .NET? – isekaijin Aug 17 '13 at 16:56
  • Java 8's functional programming is pretty good, and Java is _the_ OO language. – Simon Kuang Jul 21 '14 at 05:42
  • 3
    I dont think FP and OOP are orthogonal. Using functional constructs is not the same as functional programming. Sure using functional constructs like lambdas in Linq makes it less OO, but it still isn't functional programming. FP is where functions are first class citizens where as OOP is when classes are first class building blocks (or something to that effect - I do realise there are many kinds of OOP). Imo, the right phrasing is "there are multi-paradigm languages which lets you write both OOP constructs as well as FP constructs making both less OOP and less FP in the process". – nawfal Jul 01 '15 at 16:59
  • 7
    @nawfal, until you can point at some intrinsic features in the two paradigms and say that they're incompatible, they're orthogonal: that is the heart of the discussion. FP is incompatible with imperative programming by definition, but OOP is not limited to imperative programming. The reason we have different words for these concepts is so that we can talk about them: when you lump them together, you just force us to needlessly come up with new words. – DavidS Feb 10 '16 at 06:16
  • I agree. I think in many cases, you can consider FB concepts as the best practice in OPP. – Arman Aug 05 '21 at 07:52
33

Object Oriented Programming offers:

  1. Encapsulation, to
    • control mutation of internal state
    • limit coupling to internal representation
  2. Subtyping, allowing:
    • substitution of compatible types (polymorphism)
    • a crude means of sharing implementation between classes (implementation inheritance)

Functional Programming, in Haskell or even in Scala, can allow substitution through more general mechanism of type classes. Mutable internal state is either discouraged or forbidden. Encapsulation of internal representation can also be achieved. See Haskell vs OOP for a good comparison.

Norman's assertion that "Adding a new kind of thing to a functional program may require editing many function definitions to add a new case." depends on how well the functional code has employed type classes. If Pattern Matching on a particular Abstract Data Type is spread throughout a codebase, you will indeed suffer from this problem, but it is perhaps a poor design to start with.

EDITED Removed reference to implicit conversions when discussing type classes. In Scala, type classes are encoded with implicit parameters, not conversions, although implicit conversions are another means to acheiving substitution of compatible types.

retronym
  • 54,768
  • 12
  • 155
  • 168
  • 3
    Typeclasses are not a mechanism for implicit conversion to other types. They're a description of a set of functions defined for a type so as to provide a form of polymorphism. The closest thing from Java-style OOP would be interfaces, though Haskell typeclasses have some important differences. – Zak Feb 18 '10 at 08:48
27
  1. If you're in a heavily concurrent environment, then pure functional programming is useful. The lack of mutable state makes concurrency almost trivial. See Erlang.

  2. In a multiparadigm language, you may want to model some things functionally if the existence of mutable state is must an implementation detail, and thus FP is a good model for the problem domain. For example, see list comprehensions in Python or std.range in the D programming language. These are inspired by functional programming.

dsimcha
  • 67,514
  • 53
  • 213
  • 334