14 June 2017

Why should we learn functional programming?

A year ago, I got intensively involved with functional programming from working, that made me change my thought process and analysis extremely. In this blog we will talk about why should we learn FP and how to bring it to use with current working.

In computer science, functional programming is a style of programming which models computations as the evaluation of expressions and avoids changing-state and mutable data, even if it's overwritten with new value, data must not changed.

Let's see the main concepts of functional programming, and we will show an example code written in C#.

// first-class function.
Func<int, int, int> add = (a, b) => a + b;

// higher-order functions. 
Func<int, Func<int, int>> createAdder =
    x => new Func<int, int>(
        y => add(x, y) 
    );
    
var f = createAdder(2); // f(x) = x + 2
Console.WriteLine(f(1)); // 3

First-class function

First-class functions are functions that can be passed as arguments to other functions. You will see add() in code example above.
Func<int, int, int> add = (a, b) => a + b;

Higher-order functions

Higher-order functions are functions that can return functions. You will see createAdder() in code example above.
Func<int, Func<int, int>> createAdder =
    x => new Func<int, int>(
        y => add(x, y) 
    );

Pure functions

This is just normal functions, if we put in the same input many times, it will always return the same value, like the add(1, 2); will always return 3 as the value.

Closures

Closures are any function which closes over the variable outside a function. example:
x => new Func<int, int>(
    y => add(x, y) 
);
you will see it referencing variable x from outside.

Recursion

Recursion, or as many people know that recursive functions, is a function that calls itself until it resolves the problem. example with fibonacci:
public int F(int n) => ((n == 0) || (n == 1)) 
        ? n : F(n - 1) + F(n - 2);
That's just an example with the simple concepts, in fact there is more than this.

It seems hard and complicated? Let's see a simple way to implement functional programming.

The main key of simple way to do functional programming is:
  • Look everything as the function that receives inputs and returns output as result.
  • Avoid rewriting new data to variables, and do not mutate the state of objects.

So, why are the above concepts that are difficult to understand?
It's just tell that the language’s main paradigm is not a functional programming, but it supports functional programming paradigm.

So, I will show example from some actual work to refactoring c# legacy code to functional way.

Requirement: We have a method to validation oldest passenger age over 18 years old.
private bool IsPassengerBirthDateValid(Passenger[] passengers)
{
    var result = true;
    DateTime oldestDate = DateTime.MaxValue;
    foreach (var passenger in passengers)
    {
        if (passenger.BirthDate < oldestDate)
        {
            oldestDate = passenger.BirthDate;
        }
    }
    if (oldestDate > DateTime.Now.AddYears(-18))
    {
        result = false;
    }
    return result;
}
You'll see method there is doing something inside the loop to mutate an object in each loop. I need to refactor it to a functional way and avoid mutating the state of the object.
private bool IsPassengerBirthDateValid(Passenger[] passengers)
{
    var oldestDate = passengers.Min(passenger =>
    {
        return passenger.BirthDate ?? DateTime.MaxValue;
    });
    return oldestDate < DateTime.Now.AddYears(-18);
}
Look better? For me I say "Yes", we don't need to imagine what's going on with the current state inside the loop

After the refactoring the code is easier to read in my opinion, and it can reduce the number of lines of code as well. In fact, we don’t refactor just inside the method, and we might restructure the design of the code too. If you write in a functional style it will be easier to test too.

How about you, are you seeing the promise of functional programming yet?