At first, the term “functional programming” seems to be difficult to grasp. But let’s take a look at whether C – one of the most widely used programming languages - is a functional programming language, or at least allows functional programming. C programs consist of functions that call each other.
It is also possible to write higher-order functions that have certain functions as parameters or return values. If programmed with C, this is a very powerful tool. However, it is not yet sufficient to speak of a functional programming language.
A function in terms of functional programming is similar to a mathematical function: sin (x) always returns the same value for the same x. Functions that we write in common programming languages - even in C – can have side effects. However, there are constructs that can outsource, limit, or control these side effects. The actual program logic is then without side effects. However, programmers also have the need to store intermediate results or to store once calculated values for further computations. Functional programming languages offer so-called “lazy evaluation”. The programmer thus has the possibility to store intermediate results in a constant. However, the actual value of this constant is determined only at first use. This can also be carried out with a finer granularity, for example for a list in which the individual elements are calculated only as required. What is crucial is that, in purely functional languages, all objects are “immutable”, so they can not be modified once they have been created. For example, adding an item to a list means that this list remains unchanged. However, a copy is created that also contains the newly added item.
The advantage is that objects are easily interchangeable between threads and can be used multiple times once they are created.
With the programming language C, a replica is possible, but the required infrastructure is not available. This makes it difficult to distinguish the “unauthorized side effects” from the “allowed side effects”.
Another aspect is that in functional languages, you can typically reference values from the environment in which they are defined. The term “closure” is used for this purpose. For example, the following example is used: Write a function createAdder (x) which returns a function adder (y) for the given x. The latter again calculates for the given y the sum x + y:
Also in Java, this can be achieved relatively easily, if the function is simply packed into an anonymous inner class. The programming language C also allows such a procedure, but the process here is a little more difficult.
How can we benefit from this?
If an application is to be developed completely functionally – without changeable values and side effects – this is very helpful for multithreading. Anything that could disrupt our thread safety is eliminated. For non-functional languages we can also learn something about this: It is good to avoid alterable objects if it is possible without or with little additional effort. For objects that appear as parameters or return values of functions and methods, it is useful if they move in the system and are accessible in several places at the same time. If they are invariable and do not have a “backdoor” for changes like a unmodifiable Java collection, this is not a problem.
It should be noted that concepts of functional programming are an interesting and useful part of the toolbox of a programmer. It will be exciting to see where these ideas will lead in the coming years.