It's Time to Get Good at Functional Programming
ddj.com
ddj.com
The argument that many-core will lead to FP adoption used to appeal to me, but then I studied Erlang, and saw that its concurrency power was due to shared-nothing pure-message passing, and not due to it being functional. FP is a way to not need to share memory, but Erlang doesn't actually use that for concurrency. The thinking seems to be that inter-core communication should be coarser-grained (e.g. at the module level, not the level of recursion over a list), because it will always be slower than communication within a core.
Also, surprisingly to me, the over-hyped web services, SOA and ESB etc arguably also aim at pure-message passing concurrency.
If you actually want to do something you still have to have side effects, and that's when all that Haskell-ish beauty goes out the window.
It is still absolutely worth it to learn functional programming, it will change the way you think, it will make a better programmer in non functional languages, but it won't solve the problems of side effects.
In my (limited) experience, Haskell code to do I/O (i.e., Monads) isn't a pretty or elegant as purely functional Haskell code. A lot of Haskell's useful tricks (i.e., its beauty like the ridiculously strong type system or lazy evaluation) don't work on code with side effects.
http://journal.dedasys.com/2007/12/12/programming-languages-...
Most programmers, realistically, don't use that many languages at any given time, and if they could use fewer, they probably would. The more territory a language covers, the better off it is... well, at least as long as it can do so relatively well.
let tree = Node (Node (Leaf 3) (Leaf 4)) (Node (Leaf 7) (Leaf 8))
This value is constant, just like an integer or string constant in many languages. In other words, the right-hand side can be arbitrarily complex. And this data structure gets passed around in a very lightweight manner (by reference, not by copying).
The Java notion that values are either primitive, or objects... is limiting.
That's silly. Anyone who has worked with a pure OO language knows that there's nothing inherently imperative about the approach. Just because the most popular OO languages (C++, Java) ultimately force you to have a main() doesn't mean that a procedure is required to write OO code. That's more a reflection of the OS execution model than the language used to write the app.
I've personally written CORBA apps that were asynchronous, distributed and multi-threaded -- in C++. Object-oriented development is more than capable of handling the complexity of multi-core processing.
Several well-known Java gurus have advocated this, eg. Joshua Bloch. I worked with Ken Arnold for a bit, and a lot of the code he wrote was in this style.
The problem is that you're usually using Java because you want access to all those Java libraries, and the vast majority of Java libraries do not use this style. So you get state leaking into your program even if your own code doesn't do it.
(This is also why I'm less thrilled by Clojure than many other people are, even though I think it's a very well-designed language. The reason people are into Clojure is because it can use Java libraries and yet provides a mostly-functional language on top. But the problem isn't in Java-the-language, it's in Java libraries themselves. Unless you go rewrite the offending libraries - and this includes most of Swing, JSF, JFreeChart, the JavaBeans spec, and Calendar - you'll still run into problems. The only major libraries I've seen that use a relatively stateless style are Date and Java Collections Frameworks (both done by Josh Bloch, not surprisingly), JavaSpaces (done by Ken), and the basic String and Number classes.
This, again, assumes you can trust your libraries. A single method that doesn't follow this convention will pollute anything that calls it.
I've done things like this, in Python and to a lesser extent in Java. It works. It is pretty easy to slip up - I've had some bugs introduced because I forgot to copy a list - but it's at least a tractable problem. Gets easier if you use things like list comprehensions and slicing, which copy by default. Though Java's lack of support for closures can make this difficult.
Not everyone gets to choose their language. When I do, it's usually something saner than Java.
The point is, OO does not require that your code be executed any more sequentially than does a functional language.
OO does not require that your code be executed any more sequentially than does a functional language.
If by "OO", you mean mainstream OO languages like Smalltalk or Java, then they absolutely do have a more operational definition than a pure functional language does. Objects send messages to other objects; as a result of receiving a message, the internal state of an object changes.
An object-oriented program is not required to be expressed in terms of a "sequence of steps" any more than is a functional program. You can instantiate objects that talk to one another, asynchronously or otherwise, to collaboratively do work.
Anyone who has worked with a pure OO language knows that there's nothing inherently imperative about the approach.
Can you provide some examples of how you might write "non-imperative" programs in a mainstream object-oriented language?
An object-oriented program is not required to be expressed in terms of a "sequence of steps" any more than is a functional program
A functional program is not a "sequence of steps"; in principle, it is just a mathematical expression that can be evaluated (via some means) to yield a value (think of a SQL query or a Prolog program).
Go back and read my post -- I drew a distinction between "mainstream" OO languages, and pure OO languages. If you want to genuinely understand object-oriented programming, don't look at C++ or Java. Look at Smalltalk or Simula.
"A functional program is not a "sequence of steps"; in principle, it is just a mathematical expression that can be evaluated (via some means) to yield a value (think of a SQL query or a Prolog program)."
I know what you're arguing -- the platonic ideal of the functional program is stateless, and methods within that program have no side effects. In reality, all programs store state somewhere, and even "pure" functional languages store state (albeit at a higher level).
What I'm trying to explain is that object-oriented programming doesn't require side effects. Where functional programs use closures and monads to pass state around, you could just as easily use a functor to do the same thing. Thus, you aren't compelled to write object-oriented code in an imperative style. The difference is that OO code tends to be more explicit about the location of state variables, and calls them what they are. Functional programs, in contrast, just tuck the stateful bits into closures, and pretends that they aren't really state.