Functional Programming (λ)

5th Jan 2020 combinatory-logic; functional-Javascript; haskell;

Key points:

    In this blog post, I would try to give a very brief and easy to understand introduction to Functional programming and lambda calculus. But expertising functional programming and combinatorial logic takes time and hard-work. FP is becoming famous from past some years. And one big reason for this is that it provides parallel/concurrent execution out of the box. While there are methods like threads in C or other imperative languages to program parallel programs, But they can become extremely hard to debug.

    So, what functional programming actually is?. Functional programming is based on λ-calculus. Let me describe it in one sentence: In functional programming everything is a function.

    Now you may have heard that definition before but let me explain what "everything" means here. So, to understand this, let's first take a look at what imperative programming is. The most basic features of the imperative programming are:

    • Variables (which stores a state of something)
    • Arithmetic operators (which modifies a state of a variable, such as +,-,x,/)
    • Relational operators (which compares two variables; such as >, <, == )
    • Logic operators (which are used to connect two or more expressions; such as AND, OR, NOT)

    Using the operators, the state of a variable is modified and that's how imperative program works. Now in functional programming, all the above features are defined using functions. Yes, variables, operators and everything else is a function.

    but don't worry in most of the functional programming languages like Haskell and Scala all these functionality is inbuilt (just like imperative languages), and the compiler handles everything for you.

    Now we will understand how these complex operators are defined in λ-calculus. We will define TRUE, FALSE and AND operator in λ-calculus.

    λ Calculus

    λ-calculus is a system for expressing computation and which is based only on functions. It was introduced by Alenzo Church in 1930s. Now one interesting thing about λ-calculus is that it can be described only in three basic operations:

    1. Representing a variable. Example:
      x x is a viariable
    2. Defining a function. Example:
      λa.b function which takes 'a' as argument and returns 'b'
    3. Executing a function on an argument. Example:
      (fa) Applying the function 'f' to the argument 'a'

    Defining TRUE and FALSE in λ-calculus.

    Using only the above 3 operators, we will define TRUE and FALSE. So, lets first understand what TRUE is in imperative programming. Let's take a look at the below Javascript code.

    var d = (c) ? a : b If 'c' is TRUE than 'd' will be 'a' else 'd' will be 'b'
    So, if we think the same use of TRUE and FALSE similar to 'c' in the above code with the functional programming perspective. We can define TRUE as follows:
    λa.λb.a The function takes 'a' as argument and returns another function which takes 'b' as argument and returns 'a'.

    So, TRUE will always return the first argument. Similarly we can define FALSE as follows:

    λa.λb.b The function takes 'a' as argument and returns another function which takes 'b' as argument and returns 'b'.

    Defining the AND operator

    Now let's define the AND operator in λ-calculus. So, to do this we need a function which output TRUE only when the both arguments are true else it should return FALSE.

    If we look closely to TRUE and FALSE define above we can say that the TRUE will always return the first argument and the FALSE will always return the second argument. By examining this, we can get an insight to define AND as follows.

    λa.λb.aba This will return TRUE iff 'a' and 'b' both are true (try it out)

    Learning more about functional programming/λ-calculus

    At the beginning of this blog, I told that expertising λ-calculus require time and hard word. But, to program in the functional programming languages like Haskell or Scala, does not require that deep expertise in λ-calculus, and there would not be any need to define things from scratch like we did above, as the compiler automatically handles these (and that's why these languages are made for). But to be a good functional programmer one must have to learn how to program anything in a purely functional way.