F# your backend.
Functional languages are the future of our industry. If you're an object oriented developer looking for a modern Functional language to transition to and further your engineering skills, then I think you should strongly consider learning F#. I predict that within a few years almost all back end development, and possibly even front end, will happen in a functional language, or in functional style; not in an object oriented imperative way that we have grown so accustomed to.
It's no coincidence that we have seen so many extremly high tech companies, that make software for millions of people, transition to languages such as Scala, Haskell, more recently F#, and other functional languages. They all start out with an OO language like Ruby, Java, or Python, and eventually end up switching to something more "scalable". They have big problems and the only way to solve them is to massively distribute and parallelize.
It won't be long before that same computing environment exists, not just for big companies, but on your own devices, you know lots of cores and memory to take advantage of. But wait... that is already your computing reality, even your cell phone has 4 cores. As Brian Holley explains, in this excellent post, you must be this tall to write multi-threaded code. "If the fastest chips have N cores, a mostly-single-threaded program can only harness (1/N)th of the available resources. As N grows (and it is growing), parallel programs will win. We want to win, but we’ll never get there if it’s rocket science". Concurrency in the imperative languages we use right now is like rocket science. "Buggy multi-threaded code creates race conditions, which are the most dangerous and time-consuming class of bugs in software."
Why my outlook has changed.
I've recently found myself doing a lot of functional development in F# and I thought I would share a few thoughts.
First of all, I must confess that I have always been a SOLID guy, within reason of course. Although they taught us what functional languages are about in school, it always seemed like those languages were reserved for the mathematicians among us and not the computer scientists. Perhaps I even saw some of the benefits of functional constructs and abstractions with LINQ while using C# and .NET over the last few years. Still, I would have never made a radical move like going all functional for all the things I'm working on. That is until I joined Jet.com, whom uses F# as the primary language, and it gets used in some very advanced ways.
Functional first languages seem to do several things better. The first thing they do better is control state and limit unrestricted side effects. State and mutability are things we rarely think about in imperative object oriented languages, but they are the main reason for our headaches in today's computing world. Perhaps on a single machine with a single thread running a single app it isn't that big of deal to reason about OO code. Most of our OOP languages were made popular in that era, while functional languages were shunned. In an era where the computing reality was just that, things have changed, especially recently.
Perhaps on a single machine with a single thread running a single app it isn't that big of deal to reason about OO code.
Reasoning about state on a single app, single thread, single everything isn't that difficult and dealing with objects feels so natural. The challenges come in when you massively parallelize some work across a bunch of distributed compute nodes on the cloud. In imperative OO languages we need to jump through hoops because, after all, side effects exist by design and we need to ensure order with constructs like locks, semaphores or a mutex. The worst part is when something goes wrong; when some random bug, that only happens on the weekend when we aren't around, shows up in our code.
In those situations we need to try to recreate that state to reproduce the bug, which is very hard to do but it is most certainly due to some race condition or God knows what made its way into our code. Not to mention that this reliance on state is one of the largest contributors to system complexity. It is not that we're forbidden to use state, rather we want to contain it and use mutability in a very controlled way.
Don't get me wrong, Test Driven Development has made great strides towards eliminating bugs in our code. We are kidding ourselves, though, if we believe that TDD, BDD, or whatever tests we can concoct will eliminate those kinds of bugs completely. They still pop up and are very difficult to deal with especially when scaling in OO languages.
Getting started with F#
So it isn't the easiest thing in the world to go from an OO mindset to a functional one. F# helps by easing you into it. You can still make objects but you should really use the record types which are immutable, meaning you can't change them after you've made them. You could also make other things mutable by explicitly adding some syntax to let that happen, but you should really never do that, at least not when you first start learning the language because it eliminates all the benefits provided to you by this style of programming. So if you made a glass that is half full in your functional code, it is half full regardless which thread wants to see that glass and will never be half empty and you don't need to put a lock on the glass to make sure that's the case :)
The biggest challenge, at least for me, was going from C# to F# or from an imperative style to a functional one is not learning the syntax, because that part is easy, but rather it is changing your mindset and relying on functional constructs rather than object oriented ones. You will want to do things the same old way using loops and changing state but you should avoid that like the plague, at least the changing state part, so you can take full advantage of the functional style of programming. I must admit that by avoiding the things that come so naturally in imperative languages, I felt handicapped like someone was holding me back or tying my strong arm behind my back in the middle of a fight. I fought through that feeling and I encourage you to do the same and when using a functional language use it correctly, as they say "when in Rome do as the Romans".
In a very short period you will see the benefits of abstractions, composition, conciseness, correctness and other key benefits functional languages provide. You will have this feeling that you understand what your code is doing regardless of how many threads it's running on and you will get that not from running smoke tests, integration tests, or unit tests, but just by looking at it. I think once you get a taste of that, you will appreciate the value functional languages like F# provide and you will want to learn more.
Material to get started.
I read books, articles, and blog posts that help computer scientists leverage functional languages. I avoided material made by mathematicians talking about things like functors, monads, or monoids. If you are an imperative programmer used to an OO style, I think you should do the same, it will take a lot of the complexity away. It turns out those are simple concepts with crazy names because mathematicians got to name them. In practice, they are simple concepts and although different from what I was used to once I got over that initial hurdle it was smooth sailing.
Here are a few of those things I mentioned that worked for me to learn F#.
F# For Fun and profit - this is by far the best resource. It is in fact a book that is disguised as a website made easily digestible and God bless Scott for writing this because it is by far one of the best sources to learn F#.
There is a great list over at http://fsharp.org/. One of my favorite is the book Real World functional programming.
I have found F# to be very friendly to the imperative programmer trying to turn a new leaf. The simplicity, conciseness, correctness, and power of abstraction you learn after just a short period is amazing. In three months time I feel very productive and capable in the language and while I miss the familiarity of my favorite OO languages like C# and Java, I don't miss the crazy race conditions and bugs that used to keep me up at night.