I have heard this time and again, and I am trying to understand and validate the idea that FP and OO are orthogonal.
First of all, what does it mean for 2 concepts to be orthogonal?
FP encourages immutability and purity as much as possible, while OO seems built for state and mutation – a slightly organized version of imperative programming? I realize that objects can be immutable, but OO seems to imply state/change to me.
They seem like opposites. How does that affect their orthogonality?
A language like Scala makes it easy to do OO and FP both, does this affect the orthogonality of the two methods?
I’ve just found a wonderful explanation of the orthogonality of OOP and FP.
The basic idea is as follows. Imagine we are working with ASTs of math expressions. So we have different types of nouns (constant, addition, multiplication) and different verbs (eval, toString).
Let’s say, the expression is
(1 + 2) * 3
. Then the AST would be:To implement a verb, we have to provide its implementation for every type of noun. We can represent it as a table:
The “orthogonality” comes from the fact, than in OOP we will be implementing this table by rows: we will represent every noun as a class, which will have to implement every method.
In FP, on the other hand, we will implement this table by columns — we will write a function for every verb, and this function will react differently to arguments of different types (using pattern matching probably).
It means that the two concepts do not have contrasting ideas or are not incompatible with each other.
OO is about encapsulation, object composition, data abstraction, polymorphism via subtyping, and controlled mutation when necessary (immutability is encouraged in OO as well). FP is about function composition, control abstraction, and constrained polymorphism (aka parametric polymorphism). Thus the two ideas are not contradictory. They both provide you with different kinds of powers and abstraction mechanisms, which are certainly possible to have in one language. In fact, this is the thesis on which Scala was built!
In his Scala Experiment talk at Google, Martin Odersky explains it very well how he believes the two concepts - OO and FP - are orthogonal to each other and how Scala unifies the two paradigms elegantly and seamlessly into a new paradigm popularly known in Scala community as object-functional paradigm. Must watch talk for you. :-)
Other examples of object-functional languages: OCaml, F#, Nemerle.
You can implement functions as objects and objects as collections of functions, so there is clearly some relationship between the two concepts.
You are talking about purely functional programming.
There is no requirement for objects to be mutable. I would say that objects and mutation were orthogonal concepts. For example, the OCaml programming language provides a syntax for purely functional object update.
Not really. The lack of tail call optimization means that the majority of idiomatic purely functional code will stack overflow in Scala because it leaks stack frames. For example, continuation passing style (CPS) and all of the techniques described in the paper That about wraps it up by Bruce McAdam. There is no easy way to fix that because the JVM itself is incapable of tail call optimization.
Regarding the orthogonality of purely functional programming and object oriented programming, I would say that they are at least close to being orthogonal simply because purely functional programming deals only with programs in the small (e.g. higher order functions) whereas object oriented programming deals with the large-scale structuring of programs. This is why functional programming languages usually provide some other mechanism for large-scale structuring, e.g. the higher-order module systems of Standard ML and OCaml, or CLOS for Common Lisp or typeclasses for Haskell.
Orthogonality implies that two things are unrelated. It comes from mathematics where it means perpendicular. In common usage it can mean two decisions are unrelated or that one subject is irrelevant when considering another subject. As used here, orthogonal means that one concept doesn't either imply or exclude the other.
The two concepts object oriented programming and functional programming are not incompatible with each other. Object orientedness does not imply mutability. Many people who are introduced to object oriented programs the traditional way often first use C++, Java, C# or similar languages where mutability is common and even encouraged (standard libraries provide a varierty of mutable classes for people to use). Therefore it is understandable that many people associate object oriented programming with imperative programming and mutability, as this is how they have learned it.
However object oriented programming covers topics like:
None of this implies mutability, and none of it excludes functional programming. So yes they are orthogonal in that they are different concepts. They are not opposites - you can use one, or the other, or both (or even neither). Languages like Scala and F# attempt to combine both paradigms into a single language:
Source
Source