views:

1016

answers:

9

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?

+34  A: 

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:

  • Encapsulation
  • Polymorphism
  • Abstraction

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:

Scala is a multi-paradigm programming language designed to integrate features of object-oriented programming and functional programming.

Source

F# is a succinct, expressive and efficient functional and object-oriented language for .NET which helps you write simple code to solve complex problems.

Source

Mark Byers
I was going to question the formulation "OO is about ...", because I didn't think that defined OO (functional programming is very much about polymorphism and abstraction too). But before I had time to, you edited it to something I can't quibble.
Pascal Cuoq
Scala inventor Martin Odersky calls Scala a "post-functional" language, which stands for a pragmatic approach that combines the most useful existing features regardless where they come from. Following this schema, one could call Java a dys-functional language, which is true but slightly off-topic...
Landei
But obviously, the inventors and the distributors use these terms for marketing reasons. These quotes should be subject to discussion and not used as a supporting argument.
Debilski
I don't agree that object-oriented and functional are "completely unrelated concepts", language designers who have a good understanding of both are able to integrate these two concepts into each other. This answer might be interesting, if you want to compare the approach different languages designers took: http://stackoverflow.com/questions/3644251/what-are-your-experiences-developing-in-scala-lift/3646365#3646365
soc
@soc: Is that better now?
Mark Byers
Yes, sounds good! :-)
soc
+4  A: 

The idea of objects can be implemented in an immutable fashion. An example is the book "A Theory of Objects", by Abadi and Cardelli, that aims at formalizing these ideas, and where objects are first given immutable semantics because that makes reasoning about object-oriented programs simpler.

In this case, a method that would traditionally have modified the object in-place instead returns a new object, while the previous object persists.

Pascal Cuoq
+10  A: 

First of all, what does it mean for 2 concepts to be orthogonal?

It means they don't affect each other. I.e. a functional language isn't less functional because it's also object oriented.

They seem like opposites. How does it affect their orthogonality?

If they were opposites (i.e. a purely functional language could not possibly be object oriented), they would by definition not be orthogonal. However I do not believe that this is the case.

and OO seems like something that is built for state and mutation(a slightly organized version of imperative programming?). And I do realize that objects can be immutable. But OO seems to imply state/change to me.

While this is true for most mainstream OO languages, there is no reason that an OO language needs to have mutable state.

If a language has objects, methods, virtual inheritance and ad-hoc polymorphism, it's an object oriented language - whether it also has mutable state or not.

sepp2k
Object-oriented languages do not need to have the class/object divide: Self, JavaScript, Io, Cecil and a few (dozen) other languages illustrate this point nicely.
JUST MY correct OPINION
@JUST: Ok, I removed the reference to classes. However, to be fair, I didn't say they did. I just said if they do have these features, they're OO. I do say "if and only if" when I mean it.
sepp2k
+6  A: 

First of all, what does it mean for 2 concepts to be orthogonal ?

It means that the two concepts do not have contrasting ideas or are not incompatible with each other.

FP encourages immutability and purity as much as possible. and OO seems like something that is built for state and mutation(a slightly organized version of imperative programming?). And I do realize that objects can be immutable. But OO seems to imply state/change to me.

They seem like opposites. How does it affect their orthogonality ?

A language like Scala makes it easy to do OO and FP both, does this affect the orthogonality of the 2 methods ?

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.

missingfaktor
Here is the Youtube link for easy download ~> http://www.youtube.com/watch?v=01rXrI6xelE
letronje
My point is although oop and fp are not opposite in general there is some points in which you have to choose a funtional or a oop aprox. One of the characteristics of oop is to bind data and behaviour and in fp, although you can do it, it is not the standar. Another char. is the organization of data and the type system in a hierarchical fashion (with inheritance in most cases) to rule the abstractions and polymosphism. Maybe with fp that scene is posssible but it is not popular.
jneira
Downvoted? Wonder why...
missingfaktor
+6  A: 

For two concepts to be orthogonal means that they can be independently realized to any degree in any given manifestation. Considering music, for instance, you can classify a musical piece as to how harmonic it is and how rhythmic it is. The two concepts "harmonic" and "rhythmic" are orthogonal in the sense that there are harmonic and rhythmic pieces, disharmonic and arrythmic pieces, but also disharmonic and rhythmic pieces as well as harmonic and arrhythmic pieces.

Applied to original question this means that there are purely functional, non-object oriented programming lanuages such as Haskell, purely object-oriented, "non-functional" languages such as Eiffel, but also languages which are neither such as C and languages which are both such as Scala.

Simply speaking, Scala being object-oriented means that you can define data structures ("classes" and "traits") which encapsulate data with the methods that manipulate this data, guaranteeing that instances of these structures ("objects") are always in a defined state (the object's contract laid out in its class).

On the other hand, Scala being a functional language means that it favors immutable over mutable state and that functions are first class objects, which can be used just like any other object as local variables, fields or parameters to other functions. In addition to this, almost every statement in Scala has a value, which encourages you to use a functional programming style.

Orthogonality of object-orientated programming and functional programming in Scala additionaly means that you as a programmer are free to choose any mixture of these two concepts you see fit for your purpose. You can write your programs in a purely imperative style, using mutable objects only and not using functions as objects at all, on the other hand you can also write purely functional programs in Scala not using any of its object-oriented features.

Scala really does not require you to use one style or the other. It lets you choose the best of both worlds to solve your problem.

Tobias
+5  A: 

Like all classifications, the division of programming languages into functional, object-oriented, procedural, etc. is fictional. But we do need classifications, and in programming languages we classify by a set of language features and the philosophical approach of those who use the language (where the later is influenced by the former).

So sometimes "object-oriented" languages can have success adopting the features and philosophies of "functional" programming languages and vice-versa. But certainly not all programming language features and philosophies are compatible.

For example, a functional language like OCaml accomplishes encapsulation through lexical scoping and closures, whereas a object-oriented languages use public/private access modifiers. These are not incompatible mechanisms per-se, but they are redundant, and a language like F# (a mostly functional language which seeks to live in harmony with the decidedly object-oriented .NET library and language stack) has to go to lengths to bridge the gap.

As another example, OCaml uses a structural type system for object-orientation, whereas most object-oriented languages use a nominal type system. These are pretty-much incompatible, and interestingly represent incompatibility within the realm of object-oriented languages.

Stephen Swensen
Interesting points. Although OCaml is my bread and butter (and the "first" language to mix object-orientation with Hindley-Milner type inference), I shied away from any direct comparison. If I had not, I would also have mentioned Caml Special Light's module system, that predates OCaml by a couple of years and provides abstraction/encapsulation mechanisms that are in competition with object-orientation (they try to solve similar problems in different fashions).
Pascal Cuoq
@Pascal Cuoq - Glad you found this interesting, I've long been fascinated by the concept of classifications as man-made constructs and more than once been penalized for listing plants as animals in Scattergories.
Stephen Swensen
A: 

You can implement functions as objects and objects as collections of functions, so there is clearly some relationship between the two concepts.

FP encourages immutability and purity as much as possible

You are talking about purely functional programming.

while OO seems built for state and mutation

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.

A language like Scala makes it easy to do OO and FP both

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.

Jon Harrop
-1. You really didn't need to raise that Scala-TCO issue here. You don't leave a single opportunity to bash Scala, do you?
missingfaktor
@missingfaktor: The TCO is an obvious counter example to his statement that Scala makes FP easy. You don't leave a single opportunity to blindly advocate Scala in the face of overwhelming evidence to the contrary, do you?
Jon Harrop
Downvoting for the blatantly leading word "majority". Even in purely functional languages, the bulk of looping isn't done via explicit recursion, but via calls to the sort of higher-order functions that Scala provides perfectly well.
Dave Griffith
@Dave: What gave you that impression?
Jon Harrop
Reading and writing a very large amount of functional code over far too many years. Tail recursion is the hammer that gets pulled out when map/zip/scan/fold/reduce/etc aren't up to the job. This shouldn't be too surprising. The reason those calls exist is to abstract out as many of the common recursion patterns as possible, after all. The only exception I can think of (where tail-call is the preferred solution) is Erlang's "fake the mutable component state as tail call args" trick.
Dave Griffith
@Dave: Note that I was talking about general tail calls. For example, continuation passing style and untying the recursive knot are two common functional idioms that rely upon TCO. The functions you mention are just aggregate operators over collections but you can even hit problems with them without real TCO. For example, a map or fold over a tree with nodes containing lists of trees would use a map or fold over a list but the tail calls from your tree fold to the built-in list fold and back would leak stack space in Scala.
Jon Harrop
Perhaps the strongest evidence is that F# disables TCO in the same way that Scala does when you compile with the default Debug settings and that *always* makes my code stack overflow. Mono cannot run anything but the most trivial F# code for the same reason. So pretending that Scala "makes FP easy" in the face of this crippling deficiency seems ridiculous to me. Scala is no better than C# in this respect.
Jon Harrop
Unless I'm misunderstanding, the call to the list fold would not be in the tail position inside the tree fold in any case. In any case, I run into a tail call issue in Scala maybe once a month on average, probably less. I just don't find it to be a particularly big deal, let alone a crippling deficiency. Perhaps you need to work on untangling your dependency graphs a bit more rigorously.
Dave Griffith
@Dave: That's just it, I untangle dependencies by untying the recursive knot. An idiomatic functional technique that *requires* TCO to work.
Jon Harrop
@Dave: You're right about my example though, it needs a custom list fold in CPS like this `let rec fold k f a (T(x, xs)) = folds k f (f a x) xs and folds k f a = function | [] -> k a | x::xs -> folds (fun a -> fold k f a x) f a xs`. Still, writing such functions over heavily recursive data structures like trees without blowing the stack in Scala doesn't sound like heaven to me. Sounds more like F# in Debug mode! ;-)
Jon Harrop
+1  A: 

One thing that helped me understand the relationship between FP and OO was the SICP book, particularly the section "Modularity of Functional Programs and Modularity of Objects" If you are thinking about these issues and you have a spare weekend, it might be worth reading through the first three chapters, its pretty eye opening.

Mo Flanagan
A: 

Orthogonal. It sounds good. If you got an education you can band it about a bit and pretend. Its a bit like paradigm.

It all depends in which circles you travel in and what each type of programming technique will give you. I have read a few posts on SS and most who come from a functional programming language usual persist on the fact that you can only go functional and anything else goes against the thinking and the mind set.

Object Oriented programming is mainly about capturing state and keeping this state as localised as possible as not to be affected by anything that is not part of the object that you manage the state with. On the other hand, functional programming looks at the problem of state from a different perspective and tries to separate state from the system and reduce it down to functions. Yes you can use both techniques in your code but they both are looking at the design of software from different angles.

There has been a great deal of interest in the techniques of Functional Programming, mainly because of the management required of state when dealing with multi-core chips and parallel programming. It seems at this point in time that functional programming does have the upper hand in dealing with this however you can achieve the same effect using Objects. You just think of the problem differently. Instead of scratching you head, trying to get rid of state as much as possible, you look at objects in the design and see how you can pair them down to what the core of what they are expected to do, using design patterns, CRC and Object Analysis. Where Objects do come into there own though, and where functional programming is a lot more difficult is in analysing the real world and mapping it to an understandable computerised system. In OO for example, a person object would be an encapsulation of state with methods that act upon the persons state. In Functional programming, a person would be broken down into data parts and functions that act upon the person data, with the added proviso that data should be created once and only once and be immutable.

I must admit though coming from an OO background, that in most OO languages when dealing with Multi-core chips, I have gone the functional route, mainly by core programming design structures (such as threads and delegates) and pass pseudo data objects around. This has led me to question the techniques of OO programming as it does not seem to map well to this threaded design.

WeNeedAnswers