Why Debreuck Neirynck Uses Functional Programming
Although functional programming has been around since the early days of software development, it has been in the shadow of object-oriented programming (OOP) since the 80’s. And even before that, functional programming (or FP) was mostly the tool of theorists, usually mathematicians, since computing theory is historically a branch of mathematics. This is probably because computers actually do two things: they can calculate numbers, and they can store information. So most people find that imperative methodologies, where you tell the computer to “retrieve information, change it, and store it back” are more in line with the inner workings of a computer. Whereas “pure” functional programming even forbids changing information, which is called a “side effect”. This means that pure functional programs see data as a stream that can be guided in this or that direction, but cannot be stored or changed. This is harder to understand for humans, at least until they get the hang of it. After that, it’s as natural as imperative programming.
With the advent of cloud computing and microservices, software applications are no longer big “monoliths” that run on one computer and share the same internal memory and CPU. They are distributed over different physical machines, often in different countries or on different continents. This meant that the classical view of programs as things that change values in memory no longer holds, because there is no longer a “central memory” to change. Instead, applications now consist of multiple inter-communicating (micro-)services that continuously exchange data. This has brought a revival of functional programming, because these new distributed applications behave more in line with the functional programming-style of “data flow” instead of “memory manipulations“.
The advantages of this new structure is that applications aren’t limited by the hardware they run on, because they can scale over many computers. This allows, for instance, Facebook to serve over a billion users simultaneously. This would never be possible with a classical monolith. The downside is that it has become harder to design and develop an application like this. Communication between parts (or “modules”) is not instantaneous, but rather asynchronous and communication may even be severed (for instance, if there is a network outage). Developers need to take these factors into account.
Functional programming helps us with this. As previously stated, because it views software as processes that manipulate a flow of data, which could also be data “flowing” over a network connection. But also because it enforces “immutability” in its core. This means that you can’t even change values in memory, you have to create a new data structure instead. Of course, in an imperative system this would be an expensive operation, but functional programming platforms are optimized for this. The combination of these factors make building distributed applications much easier and less error-prone using functional programming.
Clojure is also derived from Lisp, which has been around since the ’60s but hasn’t lost any of its power and mathematical beauty. The fact that a Lisp/Clojure program is itself a data structure allows applying its own functions onto itself. This is how macros work. But this is only one of the many advantages a powerful language like Clojure offers. It allows us to create robust and performant functional programs for the 21st century. And we even have fun doing it!
So, this is in a nutshell why Debreuck Neirynck uses functional programming and why we use Clojure as our functional language.
Triggered by our view on functional programming? Interested in a collaboration? Don’t hesitate to get in touch and let’s talk about it over coffee!