Programming and parallelism: how functional languages became irreplaceable?
Intetics Senior Software Developer Iaroslav Karkunov has a few thoughts about that.
Functional languages are gaining more and more popularity and everyone seems to know at least a little about some of their elements, which can be noticed even in C++ or C#. So why would functional languages be useful for any developer? Intetics Senior Software Developer Iaroslav Karkunov has a few thoughts about that.
I switched to functional languages and I have no regrets. It was difficult at first because the world was turned upside down. But after all, I can say that these languages are even somewhat easier. I don’t want to go back. Why? Because I feel that now I can express my thoughts easier. I don’t have to be wordy and repeat myself.
Normally arguments about object oriented vs functional programming are not 100% correct. You can do a lot in both. The question is, which one requires more effort.
OOP languages tend to be imperative, meaning that the actions are done in sequence. Simply put in order to understand how the program functions, you have to interpret it in your head. Functional language normally consists of primitives that put it all “under the hood.” Its power lies in declarativity and expressivity.
If you are using cycles in C++, then you will probably be thinking in this way: this “for” executes reduction and processes the data into a new result, and that one transforms the old collection into the new one.
In functional languages, it will be indicated by some verb. For example, standard functions “map” and “fold”. The first one is for displaying the collection into some other collection with the help of a certain action, and the second one is for reducing the collection into a new result/type with the help of some function. It will be clear right away as to what exactly we did, and it will also be written in one line instead of in a huge messy construction.
It looks really elegant.
Functional constructions are approaching
I think you can be a good developer and not know any functional language. Work specifics would most probably be different. You won’t be able to write distributed systems without knowing the actor model or Erlang. However, with certain task classes you will manage quite easily.
You may also not have learned any one of the functional languages. Whether you like them or not, you will simply know certain things if you have experience. You will understand what pure functions are (when given the same input, it will always return the same output). Conversely, you may know nothing about monads.
The reason for such knowledge is the fact that OOP languages are now trying to realize functional elements within themselves.
In my opinion, lambda function is the most popular element utilized in OOP. For example, with it you don’t have to determine a separate function in order to add two. You just write «x -> x +2», and it’s clear for everyone. We receive “x” and return “x+2”. It works as a function and is very readable.
One more functional element appeared in the latest C++ standard. It is needed in order to avoid the problem of statically-typed OOP – huge signatures of the complex types that have to be stated everywhere. To alleviate this the automatic type inference has appeared. You don’t have to enter into the code the specific type – instead just use the “auto” keyword. It will find out the necessary one and if something is wrong, will tell you where the mistake is.
Or we can look at C# as an example – it’s multi-paradigm but more of an OOP. It has a LINQ library that is often used by developers to process the collections, to work with the data, and database requests. Its creator was inspired by the Haskell language and functional programming.
Languages change with the development of processors
Everything started with the hardware. Functional languages appeared in 1958. Nevertheless, historically it happened so that imperative, and then object-oriented languages suited better for hardware due to the von Neumann architecture. In the early days of computers, the data volumes were small, and the PC memory and computational power were limited. So at that time, it was more preferable to use mutability and thus, structural and OOP-languages.
Processors however, reached the ceiling in terms of the frequency in which the operations could be performed, and thus a new trend appeared – parallelism. Such processors like Core 2 Duo started to appear and they were having 2, 4, 8 and more independent cores.
But in order for computations to be done in parallel, the program has to have a very small state – it has to be decomposed and as simple as possible. Otherwise there will be a high possibility of system parts having to depend on each other. Consequently, the calling order of the functions can affect the final result.
Previous paradigms (including OOP) did not limit this state, and its small size could be guaranteed by the developer only. In functional programming it happens due to the paradigm itself. That’s why for the majority of programs in functional languages, it is easier to realize parallelization, and it works more efficiently.
C++ developer creates a prototype in Haskell
On the other hand, a person who works in OOP has to understand some peculiarities of functional programming.
There is a C++ developer Bartosz Milewski – an entrepreneur and FP popularizer from USA/Poland. He creates prototypes in Haskell before coding in C++. As a result, he gets a program that is concurrent and has a minimal state. If a developer wrote source code in C++, it would take much more time simply because the code takes more space.
In the majority of pure functional languages, you have to clearly state any change in the data and consider the context. OOP does not guide you towards that. The standard course in OOP helps you understand the syntax and how the language works.
Functional languages seem difficult because of composition
There is an opinion that functional languages are more difficult than object-oriented ones.
They allow you to easily work with function composition, and even abstract parts of the repeated code inside your particular kind of the composition. From one point of view, it’s somewhat like glue between the program parts. There is a huge variety of gluing options, and the more types of glue we have, the more expressive and fast your development process will be. Firstly, you have to learn them, and understand how to use them.
It’s unrealistic to understand it right from the start, so inside the community these efforts are somehow transformed into firm opinion. Functional languages are all about math and are incredibly hard. But don’t be afraid, instead give it a try. I think at least a year of experience will give a person a fresh view on things.
People basically solve all their tasks with only two operations. First divide the task into a bunch of smaller tasks and solve them. Then glue those small solutions into a big one with the help of the composition. This works not only in programming, but also in surgery, culinary etc.
It’s good but not necessary to know Math
Unlike functional programming languages, OOP does not focus much on how we can compose the objects.
If we have to add two and square the result, in math it would look like (x+2)^2. But even in the simplest OOP language, there is no function composition and you can’t easily write a function using the composition of the other two.
What else seems unnatural and wild is the fact that you have to reject mutability. For effect modelling, for example, to output the result on the screen, functional languages provide you with special contexts; in Haskell with the help of the monad IO – input-output. It is just a pure description of the effects you want to have, and an efficient way to markup the places where the effects are used.
It would be a plus if you know math, but it is not necessary. A developer who does not know it will think, “Weird mathematicians. They’re using hundreds of formulas and strange symbols to describe programming! Why do I need them?” But these formulas are not so difficult and can be learnt by anyone.
How viable are OO - languages?
As one of my friends says, "we’ve written so much in Java already that even our grand-children would have enough work to do." Maybe it’s a bit of an exaggeration, but the architecture of computers itself is nowadays not yet completely suitable for functional languages, and in reality, we are closer to those languages that offer mutability.
I won’t say that OOP is bad but I’d never start writing a distributive on Ruby. There is a lot of fuss with parallelism. Threads are resource-intensive and have to be strictly limited. For web it’s better to use Phoenix.
Entering OOP and other paradigms is easier and that’s why the Ruby community is so large. The FP community, while being cool and awesome, is holding on to people who believe in its bright future. I hope in some time we’ll become closer to functional languages.
Hundreds of servers all over the world should work as a whole
There is a tendency however that demand for functional developers keeps rising, and in theory affects salaries. Be that as it may, companies prefer a more flexible approach to that, and are usually supportive towards their candidates.
Those specialists who work with distributed systems are well paid. They can find a good place. there are lots of services distributed among hundreds of servers all over the world, and they should work as a whole. There are a lot of such systems, and the number of them will be increasing. Unfortunately, there is a small amount of such specialists. When there is not enough of them and the demand is high, it will be profitable.
Proprietary language does not slow down development
The language inside the project is Flow. It’s proprietary, not open source and is used only in our company. Such languages are called DSL or domain-specific language. They are intended for specific spheres and ours suits the best for graphic interface development.
Once I joined the company I was doing usual tasks. But when facing a problem, I sometimes understood that it was not my fault and something in the library needed to be fixed. I am a perfectionist, so my contribution here at work includes thinking about how to do things right from a developer’s point of view.
From a functional paradigm point of view, I got a chance to look at the development in a more mathematical way. The fact that language is proprietary did not slow me down. I got acquainted with some ideas, like reactive programming, during the course of our development.
I don’t limit myself to Flow only. It won’t be of much use in another place, but everything that I learnt from it is without doubt useful. I grew as a professional, but it also depends on whether the person contributes to their own success.
Vacancies: how to join functional developers
It’s not so hard to hop from OOP languages to functional programming as it may seem. Anyway, working in Intetics has proven one thing: for math fans, test tasks will be nothing difficult.
Another factor that may help some of you decide to give it a try is the fact that Intetics does not pay much attention to the technology stack. You only have to know at least one programming language and all your previous merits will not matter much. What matters are your results after completing all of the interview stages.
In order to completely persuade those who are hesitant Intetics also offers trainings that allow you to quickly dive into the Flow language, and the integration process itself normally takes about one month.
For those interested in a new technology stack check our job offers below.