"Study Functional Programming or Be Ignorant"
benhutchison.wordpress.com
benhutchison.wordpress.com
The best approach appears to me to be taking the best of both worlds. Functional may solve lots of problems, but you can't deny the advantages of a good OO design. Just devise your OO architecture for good reusability, flexibility, low coupling and high cohesion and then just use the best that functional programming has to offer.
There's no denying its power, and I'm sure it's superior for some applications, but the inherent mixing of persistent state and behavior in objects is pretty much irreconcilable with functional programming as I understand the latter.
For example, to me perhaps the single most useful OOSE artifact is the sequence diagram (UML version here: http://en.wikipedia.org/wiki/Sequence_diagram); in the non-side effecting functional programming world you have much less to keep track of in that manner.
To me, the biggest advantages of OOP are composition and sub-typing. Check out PLT-Racket's concept of an iterable versus that of most OO languages (http://docs.racket-lang.org/reference/sequences.html#%28def....). In PLT-Racket you have to bundle together a list of functions, essentially rolling your own v-table from scratch. In an OO language you have this nice packaged concept of an Iterable interface, which is much easier to understand conceptually.
Underneath the hood, both are doing the same thing; both are performing operations according to a specified interface for some underlying data that the consumer knows nothing about. This is encapsulated message passing, which is at the heart of the OO. The same sort of thing can be done with immutable objects like functional data structures (http://code.google.com/p/pcollections/). OOP and functional programming need not contradict one another or be mutually exclusive.
As a final note, no one codes in lambda calculus any more than anyone codes in Turing machines. Real functional languages have mutable variables, and Haskell is the only language that I am aware of that tries to hide this fact as much as possible.
OO benefits tremendously from Functional programming. It's much, much easier to develop in a system where you can treat calling most of the methods on most objects as if they were stateless. A system that uses less state is more flexible and easily changed. A system that better encapsulates state is also more flexible and easily changed.
There will be new "patterns" on how to use both features without shooting yourself in the foot. There will be new libraries written that exploit the awesomeness of both features. At the end of the day, there will be people benefited from that, and there will be more segmentation in the industry. People will have to be trained (wait... that no longer exist in our industry).
... and I... I will move on to a more managerial position so I can put to rest the learning of programming language for the sake of learning and swinging ego than for actually building things.
http://en.wikipedia.org/wiki/Common_Lisp_Object_System is probably a good place to start
Compilers are just functions from input to output, so it is easy to write them in a functional way. For example code formatter, report generator, any program in which we are only interested in the final result, not in the intermediate steps, and nothing "new" can happen in the process of computation.
Interpreters are more imperative by nature, and it is more natural to write them in imperative way. For example real-time simulations (including games), interactive apps like offices suites, crud apps, etc.
In interpreters functional programming can be used in the small scale, to implement commands, but the result will be imperative interpreter with state and commands that modifies this state.
So oop is more suited to describe domain of most programs - users think about crud apps like this: "this button changes the name of selected student", "this button deletes student from base", "this button assigns student to course". Even if under the hood there is functional code, it is in reality interpreting imperative language and operating on state.
At least that's how I see it. YMMV.
For instance, in Clojure I could write a multimethod that updates refs of type Student, and Course:
(defmethod assign [Student Course]
[student course]
(alter student update-in [:courses] conj course)
(alter course update-in [:students] conj student))
There is polymorphism and mutability here, but we're not dealing with objects.So to rephrase my question: what are the advantages of OOP when dealing with mutable state?
Great insight. Thanks for teaching me about this.
Works good till you reach a problem domain it's not appropriate for.
Models are great till you take them for reality.
I've often thought that the recent emphasis on functional languages stems from the fact that webapps are where a great deal of innovation has been coming from lately. The design of the HTTP protocol makes it particularly straightforward to think about server-side code as a series of stateless (ignoring the database) transactions. The "model" of inherently* functional tasks as compilers and inherently procedural tasks as interpreters does a good job of crystallizing this idea.
(* When I say "inherently" functional or procedural here I mean tasks that lend themselves to being expressed cleanly one way or another.)
Have heard/read similar posts from fans of other fringe languages: Lisp, Scheme, Prolog, ... There are grand claims of superiority, but with little practical evidence to bear out the claims.
I agree with other comments here -- the art of software design and programming is _generally_ independent of language. Languages, bad ones, inhibit good software engineering, and good ones enable if not encourage them (which is why good ones are typically minimal).
I agree with the general assertion that hard core OO developers (Java and .Net folks) will need to start learning some new mental models of programming to keep adding relevance. I think we will start solving some harder problems that are intractable with traditional OO mechanisms.
I think as we migrate our data towards more flexible structures and look more towards asynchronous parallel processing, we may find that splitting out data and behavior serves us better than tightly binding them as OO methodology does.
I think ultimately we will treat our code and data as the same thing, just from different perspectives and levels of abstraction. I'm not sure most OO programming environments today support this notion easily.
I do think we will be solving harder problems, but what exactly they are falls into my unknown unknowns category.
But when I see post like this I always think to Fred Brooks' "There's no silver bullet" paper (http://en.wikipedia.org/wiki/No_Silver_Bullet).
If an OO programmer never knew functional programming, yeah, sure, he'll be a better programmer after learning LISP and I think the vice-versa is also true, a functional programmer who never bother learning OO because he thinks his paradigm is the silver bullet will benefit more knowledge if he decided to learn OO.
There are evangelists and purists in both world.
Here's a challenge for all evangelists and purists: you keep telling people that your thing is the right way to go, but when I ask you to learn my thing, you refuse like a mad man.
IT is a very funny industry, people keep telling you that we change the world, we have the power, we have the edge, we're the future or whatever. But at the end of the day, don't tell us to change ourselves.
The bit that stirs me up is that this “stuff” isn’t, repeat is not, Haskell-specific. Its rooted in the fabric of our reality, in our mathematics and our problem domains, and bits poke up like the tips of icebergs into mainstream OO languages, their true structure part-revealed. But rarely in the OO-world have I found such carefully abstracted and subtle techniques of programming in daily use.
Ideas from Haskell & Functional Programming will continue to flow into the mainstream over the next couple of decades.
This is why it's important to read about things like immutable data structures and higher-kinded polymorphism, even if your problem domain (or personal / corporate style) is utterly unsuited to existing functional programming languages. This stuff isn't just obscure tricks for maths nerds to obsess over, it's fundamental to how programming works.
If you want to understand LINQ, you need to understand higher-kinded polymorphism and monads. If you're writing a series of chained callbacks in Javascript and feel like there's some repetition you'd like to extract but can't quite put your finger on, you need to understand the continuation monad (I'm only about halfway there...) If you want to reason sensibly about concurrent updates to complex data structures, it helps a lot to know about immutable structure-sharing data structures.
Lots of languages are incorporating functional features, from dynamic languages like Python to even Java's support for closures. To really get your head around these features, it pays to play with a real functional language for a bit.
What happens when you want to program for more than ten CPU cores?
I recently took a course on concurrent programming, and the from what I learned, some problems are easier to deal with in erlang or something similar. But then again some aren't. And a lot of the time, they run an order of magnitude slower (though as my prof would say, correctness is sometimes more valuable than speed).
And granted my Erlang program for matrix multiplication was very concise. My MPI implementation ran WAY faster.
It seems to me, there are two schools of thought, and you can live in one, the other, or both. Certainly there are things to be learned in either.
I think all one can take away from articles like this is that it's good to keep learning.
Try to convince someone of the value of immutability without mentioning concurrency.
Imperative and functional programming relate in the same way that arithmetic and algebra relate. It is hard to do deep reasoning in maths without algebra and it is impossible to evaluate the value of most algebraic expressions without arithmetic.
There is a reason that functional programming is at the forefront of concurrency research. In the long run, imperative only approaches will be unable to compete, and functional only approaches will remain on paper.
OO programmers who understand functional programming have a big advantage over OO programmers who don't. Learning FP gives one the mental tools to do better encapsulation.