I've recently been taking look at Java 8 and have got hold of "Java 8 In Action" published by Manning. The first thing that struck me is how one of Java 8's unique sales propositions is functional programming; functions are now first class variables, you can pass them around your code as you would an int or a String. This is a big change.
So, why is there this change in direction? You could probably come up with several reasons, but we’ll begin with the premise that industry best practise changes over time and even the most popular languages will one day fall out of favour. I imagine that if you're young enough there will be a day when you'll look back and say "remember when we used to use Java”? Before looking at why there is this change, let’s reflect on how we got here by stepping back to the 1980s...
According to Wikipedia the IBM PC was released on 12th August 1981. The first PCs shipped with BASIC1 although the cool guys soon got fed up with this and moved on to Borland’s Turbo Pascal. Turbo Pascal’s coolness didn’t last that long because Microsoft bought out Microsoft C (or MSC), which soon became the defacto standard. It was cool because if you were clever you could access the hardware directly using int 21H, int 10H and int 14h and others, and if can remember which interrupt did what, then you’re old like me2...
UML. This was a fusion of the Booch Method, James Rumbaugh's OMT and Ivor Jacobsen's OOSE and it was de rigueur when it came to designing software. All kinds of tools were available for the job of documenting and communicating your designs and, from experience, some of these were of very questionable quality, which in begs the question: were the developers actually using UML to write their UML programs? If so, then those products weren't really a good advert for UML.
You don't see as many organisations using UML these days, though I still do when I need to get a design straight in my head. My first choice of UML tool is, and always will be, pencil and paper. It's simple and it works.
The thing about this broadly made up timeline is the under pinning concept of imperative programming. In summary, assembly language gave rise to C, C to C++ and OO, and C++ and OO lead to Java - all imperative. Wikipedia gives a good overview of imperative programming, so I’m not going into it in detail, but I’ll summarise imperative programming as programming with functions AND mutable state, meaning you can have instance and global variables.
How does functional programming differ to imperative programming? The main idea is that functions are data, just like integers and Strings; algorithms are implemented in terms of function calls (while and for loops do not exist, you use recursion) and variables are always local.
So, what’s changed? The common answer to this, one that put about by Erlang developers and one you’ll find in Manning’s Java 8 book, is that hardware has changed. ‘Computers’, at least the one’s you’ll find in a server room, are now a sophisticated multi-processor, multi-core affairs with terabytes of memory. Take, for example, the HP Proliant DL580 G8 server; it has up to four processors and each processor can have up to 15 64bit cores. That’s huge, especially when compared with the original, revolutionary 16bit Intel 8086 on the original IBM PC. Assuming you’re running Unix and you ran the top command, then maximum processor usage would be given as 6000%. Given this dramatic rise in machine power we software developers need languages that can support them allowing us to easily use all this concurrent processing power and that’s were functional programming comes in.
In imperative programming you can have instance variables, global variables and mutable state. These can be shared between threads although sharing these resources is costly and inefficient in terms of synchronisation and locking. It’s also fairly slow and difficult to do as you have to avoid deadlocks and other similar problems. Functional programming does away with all these problems because it does away with all the tedious mucking about with instance variables and state. That means you don’t have to bother with locking and synchronisation and thread or processes (call them what you will) can be independent of each other.
That’s the theory, but does it hold up to scrutinisation? Let’s not forget that it’s possible to write good multi-threaded programs that effectively use the many cores of a large multi-core and multi-processor machine with imperative Java 6 or 7. Just like functional programming languages you have to think about what you’re doing, plan out a suitable design and execute it using business ‘best practice’. Just because Java 6 or 7 is an imperative language, you don’t have to share data between threads/processes and use synchronisation and locking, it’s just a matter of design. The logical conclusion of this is that you can do without functional programming, which leads to possibly the real reason behind the popularity of functional programming languages: people enjoy using them.
You could therefore say that functional languages are the “latest thing”; a craze, they’re trendy, a fashion. I have to emphasise that 'fashion' in software development is not necessarily a bad thing and is nothing new. If you go back to my potted history above you’ll see that the time-line is full of trends and crazes: the adoption of ‘C’ over Turbo Pascal and BASIC, the paradigm shift to Object Orientation and even the move to Java with it’s compile once and run anywhere promise.
Is it Imperative that you learn Functional Programming with Java 8? Ask me in a few years time...
1All historical facts in this blog are guaranteed inaccurate by my failing memory.
2Correct me if I'm wrong, but int 21H = MSDOS Functions, int 10H = direct screen access and int 14H = serial I/O