3

A novice's introduction to Functional Programming

A simple and practical introduction to Functional Programming


A novice's introduction to Functional Programming

I was struggling for many months just to understand what really is Functional Programming. I found it very complex and insane in my early days of learning. Then I realize that it was not the problem with functional programming but was mine. I was doing a mistake of learning it heavily comparing with Object Oriented Programming which I am comfortable with. Just like they say "comparing apples and oranges".

After I realized my mistake, I learned it with a fresh perspective. And surprisingly it was getting into my mind like a magic. Now, I wouldn't say I am a hardcore functional programmer (or even a functional programmer, I haven't really worked on any pure functional programming languages!). But, I was able to understand the concepts of functional programming. Based on my encounter with functional programming, here I am trying to explain the functional programming as simple as I can.

What is Functional Programming?

We are familiar with Object Oriented Programming and most of us use that approach to write our daily dose of programs. Similar to that Functional Programming is another paradigm which defines certain ways of writing a program. So it is basically a style of programming.

Functional programming is inspired by mathematical functions, specifically from lambda calculus, a formal system developed in 1930 by Alonzo Church to represent computation.

Functional programming is invented around 60 years back (First functional programming language is LISP invented in 1958), but it was very rarely used for software development. For the last few years, it becomes very hot topic and you can see many articles, talks, and videos about it.

There may be several reasons and the major reason we can think of is the need for concurrent programming. Since the internet is growing rapidly, high-end processing power is needed to handle the different process and the vast amount of data. Concurrent programming is effectively used to split the processing power into a different core or even different systems. Functional programming can support concurrent programming with great reliability. So big players like Facebook, Amazon, Twitter etc. are using functional programming languages to write their heavy processes.

Another reason would be JavaScript. JavaScript has good support for functional programming even if its a multi-paradigm language. So JavaScript developers started writing programs in the functional way recently. You can see many functional programming talks is by JavaScript developers(like me!) even though they haven't worked on any pure functional programming languages!

Functional Programming Concepts

Just like we have Object Oriented Concepts (like Inheritance, Polymorphism etc.), functional programming has it's own concepts too. Let's discuss a few basic concepts of Functional Programming.

Pure functions

Pure functions are normal functions with a few additional rules.

  • It should take parameter(s) and should return a value
  • It should not access or modify any global variable
  • It should not have side effects (writing to a file, reading database etc.)
Pure functions always return the same result for the same set of inputs, because it only processes its parameters and returns the result. It doesn't need any language support to write it because the rules are very basic. But some pure functional programming languages force the developer to write pure functions since functional programming states that all the functions of a program should be "pure functions"!
// PURE FUNCTION EXAMPLE 
function sayHello(greet, name) {
    return greet + " " + name;
}

alert(sayHello("Hello", "Sam")); 
// Output: Hello Sam

Lambda functions

Lambda functions or anonymous functions are functions without a name. Lambda functions are building block for many of the concepts in functional programming. See an example of a lambda function.

function (a, b) {
    return a + b;
};

First-class functions

This is a programming language feature. If a programming language supports first-class functions then it treats functions as first-class citizens.

For example, in normal programming language what we can do with functions? We can "define a function" and "call a function", that's all. But in the case of a data types (string, int, double etc.) we can do many more things like...

  • Assign values to it
  • Pass it to a function as argument
  • Get it as a return type from a function
Consider we can do all of this with a function too, then we can say the language has "First-class Functions" and we can...
  • Pass functions as arguments to other functions
  • Return functions as the values from other functions
  • Store functions in data structures
Here is an example of assigning a function to a variable
var fnSum = function (a, b) {
    return a + b;
};

Higher-order functions

Higher-order functions are a type of function which does at least one of the following.

  • Accept other functions as arguments
  • Return other functions as results
To write higher-order functions the language need to support First-class functions. Following is an example function which returns another function as result of a function.
function foo() {
    return function() {
        return "Hey there!";
    };
}

var bar = foo();
console.log( bar() );
// Hey there!
This is the famous syntax of jQuery document ready function, not sure if you have noticed it before, but "ready" is a higher-order function which accepts a function as it's argument!
$(document).ready( function () {
    //do some stuff
});

Immutable data

In functional programming modifying the value of a variable is considered as a serious sin! The reason is to improve readability and runtime efficiency of a program and make it thread-safe. So it recommends the use of immutable data type whose value cannot be modified after it is created. If you want to change the value you need to create a new variable and assign the new value, the existing value cannot be modified.

int i = 42; // Initializing value

i = 43; // re-assigning the value is not allowed
i++; // modify the value is not allowed
i = i + 1; // re-assigning the value is not allowed

Tail recursion

We know recursion is a function calling itself. But what is Tail Recursion?
It just adds a simple specification to recursion, the recursion call should be at the end of the recursive function. So there is a guarantee that nothing is left to execute in the function after a recursive call.
Here is an example of a tail recursive function. You can notice that the last thing does in this function is the recursive call factorial(n - 1)

function factorial(n) {
    if (n <= 1) return 1;

    return factorial(n - 1) * n;
}

var fact = factorial(4); // 24
And here is the same function without tail recursion. Here you can notice that there is some more calculation is doing after the recursive call, that make the function not a tail recursive function.
function factorial(n) {
    if (n <= 1) return 1;

    var fc = factorial(n - 1);
    return n * fc;
}

var fact = factorial(4); // 24
But why the tail recursion is so important for functional programming?
Functional programming recommends the use of recursion instead of loops, because loops are bound with mutation of the variable. But recursion has a performance issue, it creates call stacks for every recursive call and that burns the memory. And if we use tail recursion, it can use one call stack for all the recursive calls of a recursive function and that optimise the performance.

Lazy evaluation

Lazy evaluation is an evaluation strategy which delays the evaluation of an expression until its value is used. Strict evaluation always fully evaluates function arguments before invoking the function. Lazy evaluation does not evaluate function arguments unless their values are used.
Let's see the following 3 examples. We have a function getLength() which returns the count of elements in an input array. The same function is written in 3 different languages JavaScript, PHP, and C#. While we execute the program these are the result we get...

  • JavaScript => Gives correct output
  • PHP => Gives output, but with a warning
  • C# => Shows error and execution terminates
JavaScript
function getLength(arr) {
    return arr.length;
}

var len = getLength([1/2, 40, 2/0, 56]);

console.log( 'Length: ' + len ); 
PHP
function getLength($arr) {
    return count($arr);
}

$len = getLength([1/2, 40, 2/0, 56]);

echo 'Length: ', $len;
C#
public int getLength(int[] arr) {
    return arr.Length;
}

int len = this.getLength(new int[]  { 1/2, 40, 2/0, 56 });

Console.WriteLine("Length: " + len);
Why PHP and C# show errors? Why didn't JavaScript show an error?
The reason is an element (2/0) in the input array is invalid, the division by zero is indeterminate! That gives the answer why PHP and C# show errors, but why not JavaScript? The reason is the function never uses the value of the elements of the input array, so JavaScript never validated the parameter. That is called Lazy Evaluation. And if we change the function to use any of the elements, then JavaScript also starts to show error.

What more in Functional Programming?

There is more advanced topic in functional programming. To avoid unnecessary confusion I would recommend to learn them only after you through with the previous topics. These are few of those topics you can add to your bucket list.

  • Referential transparency
  • Currying
  • Closure functions
  • Monads
  • Map, Reduce, and Filter
  • Functional compositions

Why should I learn Functional Programming?

That's a pretty obvious question. Many of us try to learn functional programming because everybody is talking about it and we don't want to be the odd guy. Yeah, that's a good reason, but there are other valid reasons too.

  • Many languages are adopting functional programming features. And you can catch them easily if you already know the theory.
  • Many languages are already using functional programming like syntax, for example, LINQ in C#, Array functions (Map, Reduce and Filter). And it makes more sense to your daily programming.
  • Functional programming handles a problem in a different way than object oriented programming. So you get new ways to look at the problems.

Functional Programming languages

Many languages support functional style programming even though they do not strictly follow the functional programming concepts. But there are languages that strictly follow the functional programming concepts too. Here are some list of major functional programming languages...

  • Clojure
  • Haskell
  • Erlang
  • Lisp
  • Scala
  • Scheme
  • F#
  • OCaml

Conclusion

Functional programming receives a lot of criticism as it has cryptic concepts. But understand the functional programming concepts is not a big deal if you take the right path. It is simply another way of writing a program, no more than that. Also, there is many fights and talk that say "functional programming is the holy way of programming" (probably because it has pure functions!). And I would say that's a myth! every programming has its own advantage and disadvantages. At the end, everything is just a compiled bytes!!!

Happy Coding!


Programmer in PHP and C# with added interest in JavaScript, jQuery, Bootstrap, HTML and CSS. I have my main interest and focus on web technologies. Believes the code should be as beautiful as the design.

Comments