I recently started a new project at my work. We made a open-minded team, with aptitude to test new technologies, and I was really wanting to start one of our API's using F#, Microsoft's bet to functional paradigm in .NET infrastructure. After commenting a bit on the subject, my team agreed quite fast on let me develop it, as long as I explained things to them, so we made it, and it is becoming a case of success.
I was holding myself from sharing any kind of motivation to use funcional programming because I wanted to see it from myself, working on an enterprise project. Since I made it work surprisingly easy, I decided to start a series of posts, trying to show my opinion about functional paradigm, and why nowaday's developers should try it.
I think that a good point to start from is answering a question that many old object-oriented paradigm developers have in mind: why functional programming?
I think this is the most simple reason to try it. Functional paradigm is more appropriated to nowaday's developer's needs. The growing necessity of resilient, geographically distributed, fault-tolerant, fast systems, are not, most of the time, embraced by the already known object oriented paradigm. And why I say that? Because I believe there is a historical explanation to it. Object-oriented languages started to become popular on an era where developer's were trying to not only shape things of the real world into representations of them (our famous classes and structures), but also we became accostumed to manage states. Look at a graphical interface: buttons, checkboxes, radio buttons, lists, scrollbars. Every single of those elements have one thing in common: they store and change states. You click a checkbox, and the "Checked" property becomes true. You click an item of a list, and the property "Selected" of it it becomes true. The same way, storing data in databases can be viewed as stateful representation. We got used to that. In fact, we got so used to it, that when web development started to blow, our first tools were things like ASP.NET WebForms - something to make us feel comfortable to build a stateful application at the Web.
Not much later, this development method started to change a lot. Web standards were reinforced, and a stateless approach (which is the real one for HTTP) started to gain focus. Not only that, but business applications started to face challenges with ever growing enterprise needs: they became distributed, not only locally but globally; processor's speed stopped growing, giving space to multi-cores, security needs became more intense, and runtime failures needed to be quickly solved, or, at least, tolerated without services becoming unavaliable.
And then developers started to suffer. Our focus was shifted from our stateful representation to complex business logic, parallelism and side-effect painful experiences. We started to discuss approaches to every new problem we were starting to face, using our already accostumed methodology: parallel task libraries, locked variables, classes and interfaces to represent our business behaviour and processes, and so on.
But in fact, we may have forgot that our old paradigm is better for other kind of job. This new way of building software is not focused on it. We are now more focused on processes, business logic, paralellism and fault tolerance. We need to eliminate or reduce (at least) side effects. We need to know, beforehanded, every input and output of our systems when planning it.
What is functional programming?
Functional programming is, in the most simple definition, a paradigm that treats computation as the evaluation of mathematical functions, and avoids states or mutable data. We have data loosely coupled to functions, abstractions are made by functions, and the value of a term is always determined by it's input. We shift our central activity from composing and extending objects to writing and composing functions.
The first thing to note is about is the avoidance of mutable data. This is extremely discouraged by functional paradigm, and it should be common on our applications. Mutable data and stateful operations leads to many problems in distributed systems, as global variables, side effects, and so on. I'm used to give a curious example where, when a bug occurs and it is detected by a customer, we need to "reproduce" it to understand how it happens. And this happens because an effect was not mapped by ourselves beforehand.
The second thing to note is how the application of functions in a mathematical sense helps us to be precise on our complex domain logic. Mathematical functions have some properties that helps us to model our data and processes in a way that we should not be able to have side effects (a.k.a. pure functional programming).
A pure function is a function where the return value is only determined by its input values, without observable side effects. We call the input the domain (sounds familiar?) of the function, and the output, the range. When developing a function, we should ask ourselves about the domain of it, and if it can treat every single input of it, and give the expected output, without being affected by outside effects (global variables, states, system changes, and so on).
Obviously, there is no 100% pure functional system. Things as I/O, for example will always be done as impure functions. But this is a subject that I want o talk about in a future post. The thing is, at least in your domain logic, everything should be made of pure functions. This makes your system safer against unexpected domain code behaviour. And when it happens, you should be able to guess that it must not be a domain problem.
Also, it requires us to know very well our domain. If we don't know everything about our domain, we can not write a pure function the way we expect it. Functional approaches makes us think more about our logic, and understand better how our system should deal with it.
What do I need to learn it?
If you ever were interested in learning, you probably got scared at first, specially if you are an old guy of OO. For people like us, FP is like re-learning how to code. However, this should not hold you on your way to learning. There are some tips you can follow to guide you so you don't get lost on it.
1. Stick to the basics, until you master it. Don't try to understand everything at first. When you learned to code, you did it too. Don't forget the baby steps. Focus on learning how the paradigm works, and exercise for long the basics.
2. Good will. Don't fear it. It's intimidating to see so many new terms like monads, monoids, partial application, lambda, and so on. Once again, how many terms did you learn in objected oriented programming? I know a lot of names to design patterns!
3. Don't try pure functional languages yet. Look for functional-first language, so you can use both OO and FP in your code. This way you can focus on baby steps, doing what you are learning in a functional manner, and doing the rest in your traditional OO manner. As you progress on it, you can always refactor your code to learn more. I'm going to use F# as the learning language of my series of posts, but if you aren't comfortable with .NET architecture, there are other options for you. A good alternative is OCaml.
4. Good examples. FP is famous for academic and scientific applications, but if you are a enterprise developer, you should look for enterprise applications. A good place to learn it is F# for fun and profit, a nice website focused on many tutorials, step-by-step, on how to learn functional programming and F#.
5. Have fun! Learn to think functionally will remodel your mind, believe me. You will think better on the steps to solve your problems, and focus more on them than on reaching requirements of the compiler. If you liked a lot to learn how to code, you will feel it again, specially if you can use it in production.
What to do next
In a very short way, those are my reasons for learning how to code functionally. I believe that learning it is important, not only because of the constant growing in market uses of it, but also to re-think our coding process.
On the nex post, we are going to talk about the basics you will need to know in F# so you can port your OO code to FP. I am going to take a little trip on F# functions, tuples, types, and how the language works with the .NET ecossystem being a functional-first language. If you are a seasoned C# developer, you may like it. Give it a try and see for yourself how it works.