Young hacker smiling

We hack your software

zero false positives

Expert intelligence + Specialized technology
DXST - SAST - IAST - SCA - DevSecOps
White Box - Gray Box - Black Box
Attacking Web Applications, APIs, Mobile Apps
Client-Server, Servers, Networks, IoT Devices
ICS: Industrial Control System

Rubber ducks depicting Karl Marx

Why we go functional?

Functional vs Imperative
An analysis of why it is necessary to go functional even with non-functional languages. Benefits of functional programming. A comparison between the imperative and the functional. How Fluid Attacks migrate from object-oriented to functional in a non-traumatic way.

In 1848, Karl Marx released into public opinion a controversial document called The Communist Manifesto. From then until today, for better or for worse, this document has influenced societies. If you have ever thought that the government is not doing its job well, that they are draining your life on taxes or that the state should not exist, you should probably read the manifesto. But my dear comrade, this article is not a communist declaration, quite the opposite. We just want to rescue an idea of the bearded Marx: The state should not exist.[1]

With the motivation of developing a programming revolution (not a social one), the functional paradigm has been strengthening in the communities of developers and in the large technology companies. Of course, Fluid Attacks is not the exception.

Little girl judging with her look
Figure 1. Your face until this point.

Maybe you are wondering what are we talking about? what is functional?. Do not despair. In a nutshell, functional programming aims to solve the question What are you doing? instead of How are you doing? proposed by object-oriented programming. For this, functional programming has a special feature: it is stateless, meaning that, programs does not save or share information through data structures, forcing functions to not modify that information. Functions use inputs just to create new information in the output. You can look at the following example to understand the difference between functional and imperative:

Javascript function for multiply 2 integers, imperative and functional approximation.
// Multiply function in an imperative way.
class Integer {
  constructor (number = 0) {
    this.number = number;
  }
  multiply (x) {
    this.number = this.number * x;
  }
}
const myInteger = new Integer (2);
myInteger.multiply (6);
console.log (myInteger.number); //12

// Multiply function in a functional way.
const multiply = a => b => a * b;
console.log (multiply (2) (6)); // 12

More benefits, less problems.

At the Fluid Attacks headquarters we made some investigation, dust off some old books and look under some stones to discover that true benefits of functional programming lie where imperative programming has flaws. The first advantage is the possibility of using laziness, which allows to delay the evaluation of an expression as much as possible, usually until the result is strictly required. This brings out another important benefit. The functions cease to be “imperative”, now the runtime has more control on what is executed and at what moment, so like electricity in a circuit, it is always going to take the shortest route.

If throughout your life, you have programmed in C language, you probably remember that for each variable, you had to assign, through the malloc function, the number of bytes the variable would occupy in the computer memory. This was a complete headache, it brings you down almost at the machine level. The functional language seeks to separate the developer from all these trivialities of execution so he can concentrate completely on solving the problem.

For us, the jewel in the declarative crown is the improvement of code structure and understandability. Now, any new developer who joins our team, can understand more easily what is being done. This is a great time saver both for analyzing and debugging.

Another important benefit is related to the correlation between the mutable state and the tests: more of the first requires mores of the latter. The mutable state brings with it, side effects that are generally unexpected, leading in the need to create more tests to avoid surprises, so we can infer that a functional code allows to generate fewer tests to cover more functionalities.

A stateless world also gives the benefit of referential transparency, defined as the capacity of replace an operation for its result and achieve the same effect. This can be achieved only if the operation is deterministic (for same inputs, same outputs), isolated from the rest of the environment and obviously being stateless.

Student asking to teacher in classroom
Figure 2. Main problem with imperative languages.

Why now?

The functional paradigm is not a new topic, in fact, it has its origins in theories about lambda functions and recursion developed in 1930. In the 50’s, LISP was born, the first language with functional characteristics, since then, many languages with similar characteristics have emerged: Clojure, Haskell, Scala, etc. [2] But why just in recent years is that this paradigm is resonating so much?.

The functional language was overshadowed by the existence of object-oriented languages such as Java and Python, which propose a greater facility to code for the general public. During the 20th century, functional languages ran slower than object-oriented languages, a problem related to the low capacity of the processors at that time.

Two people talking about functional language
Figure 3. Probably the situation of all functional languages in the nineties.

Today, the hardware barrier was overcome. The biggest motivation to use functional is that currently the applications are too complex and huge, with users flow that exceed millions per hour, so deficient functions which do not allow flexibility, concurrency and parallelism in their execution are no longer profitable. Functional approximation brings us an immense scalability, a fast maintenance and robust expressions with long useful life.

Why us?

Why a company in the information security business is worried about being functional? The answer is simple: We want to do it right at the first time, we want our code to be an image of the quality and good practices on which Fluid Attacks stands. We are sure that the code will be excellent from the begin because we think functional, there is no room for ambiguity, there is no room for side effects. Something does what it says and nothing else, period. All this on a clean and understandable code even for the freshmen in the deep waters of coding. Do not believe us? Check it yourself in one of our flagship products: Asserts.

Functional in non-functionals

Maybe you’re thinking that the benefits are really good, but you are an OOO (Object-Oriented Obsessive) and all your code is in an imperative language. It’s normal, it’s okay to be a little reluctant but do not worry. Here in Fluid Attacks, we are like you, we use object-oriented languages and that did not stop us from being functional. All languages can be functional. In fact, most languages have declarative characteristics through libraries with methods that reproduce functional behaviors quite well. Now you can read the docs. In general there are some keys that you must follow to be functional in a non-functional language:

  1. Avoid the use of classes and classes attributes. Use classes only if strictly necessary (life or death matter).

  2. Create granular functions that only do ONE thing.

  3. Functions must be deterministic (you already know what is deterministic).

  4. Minimize the amount of data structure.

  5. Understand a list as the "first item" and the "rest of the list" and not as indexed values.

  6. Store for late. It is preferable to check if a list is not empty to have to perform an operation again.

  7. Use recursion and primitive functions instead of loops.

  8. Do not use global variables. (The queen of the state-keepers)

Change your way of thinking instead of your code syntax!

Migrate from imperative to functional is not easy. You can see and analyze thousands of lines of functional code and still not understand, it is not because the syntax is more difficult, it is because you just keep thinking in an imperative solution!. Before you even start thinking about reading the documentation of the functional module of your favourite programming language, first stop going directly to apply a very specific implementation for a particular problem, better take the time to learn where you can apply high level abstractions in your problem. [3] In this business is necessary to think outside the box, categorize the problems in a different way, seeing the common points of your implementation.

Conclusions

In addition to discovering that Karl Marx would have been a functional programming genius, we now know that functional programming is not a matter of fashion, it is a matter of survival:

It is not the strongest of the species that survives, nor the most intelligent that survives. It is the one that is most adaptable to change.
— Charles Darwin

Surely you are thinking that it is a lot of time analyzing and less on the keyboard, that you have the pressure of your boss on your shoulders, that there are deadlines to be met, however, think ahead, how much time your imperative code will start to rust? Probably, you will have performance problem thanks to the endless tangle of methods and classes, code will eventually rot and end up being devoured by scavengers. so, think ahead, go functional.

References

  1. Marx’s theory of the state

  2. Functional Programming

  3. Functional Thinking: paradigm over syntax, Neal Ford, book, 2014


Author picture

Oswaldo José Parada Cuadros

Mechanical Engineer

Family, friends and little details. There is the answer.



Related




Service status - Terms of Use