Understanding the Basics of Functional Programming

ยท

6 min read

The Concept of Functional Programming

Functional programming and concepts related to functional programming can be difficult to understand and gets overwhelming very quickly, especially for beginners. Doing a quick search on functional programming brings out keywords such as pure functions, mathematical functions, immutability and the list goes on. In this article, I aim to give you a basic understanding of what functional programming is and some popular concepts around it.

To better understand the above-mentioned concepts, let's look at some building blocks of a program.

First is a variable. A variable is a name used to represent data stored in a memory location. A variable can hold strings, integers, booleans, or some reference types such as arrays, objects, etc.

var myVariableName = 10

var myArray = [ 2, 4, 0, 10 ]

Next is a function. A function is a reusable piece of code that performs an action. Below is an example of a function that adds two numbers. I would be using Javascript for the code snippets.

function calculateSum (numOne, numTwo) {
  return numOne + numTwo
}

This simply takes two parameters and sums them up. Cool ๐Ÿ˜Ž Variables and functions play an important role in programs, they hold the data in our programs, and from my point of view, functional programming is all about how this data is manipulated and shared.

Functions are used to manipulate variables, arrays, objects, and the other constructs we use to write code. Let's look at two important concepts about functions when talking about functional programming. These two concepts are side effects and pure functions

Side Effects

Wikipedia does a good job of explaining what side effects are, according to Wikipedia :

In computer science, an operation, function or expression is said to have a side effect if it modifies some state variable value(s) outside its local environment, that is to say has an observable effect besides returning a value (the primary effect) to the invoker of the operation.

An example would explain this better.

var finalResult = 26

function calculatePrice(price, quantity){
  var amount = (price * quantity) + finalResult
  return amount
}

The variable finalResult is outside the scope of the calculatePrice function but then it modifies the output of the calculatePrice function making it impure. This is an example of a function having side effects.

Imagine you had a large complex code base with variables that had their state affected and changed by functions, overtime as the code base grows it becomes very difficult to debug and test because the state of variables keeps changing.

A solution to this problem is writing pure functions. The next topic talks about pure functions

Pure Functions

giphy-pure.gif

By now you might have a guess about what pure functions are from the previous paragraph, let's dive a bit deeper. The definition of a pure function is easy to understand, a pure function takes input and produces or returns an output based on the input it receives.

A quick example:

function calculateSum (numOne, numTwo) {
  return numOne + numTwo
}

The return value of the function above is based on its inputs, which makes it pure.

A pure function does not modify or mutate the state of variables outside the scope of the function. Another thing to note about pure functions is they provide the same output when given the same input. Let us call the calculateSum function and pass arguments of the same value over and over again.

console.log(calculateSum(10, 30))
console.log(calculateSum(10, 30))
console.log(calculateSum(10, 30))

Above we are providing the same input that is 10 and 30. Guess what the output is always going to be, yes! you are right it is always going to be 40. This is a perfect example of what a pure function is unlike the impure function calculatePrice which when provided with the same input is not guaranteed to produce the same output since the value of finalResult can change at anytime.

This leads us to a new concept, Referential Transparency . What is Referential Transparency ? I know you might be thinking 'You promised to keep this simple ๐Ÿ˜‚ ', well this is simple, according to SitePoint:

In functional programming, referential transparency is generally defined as the fact that an expression, in a program, may be replaced by its value (or anything having the same value) without changing the result of the program. This implies that methods should always return the same value for a given argument, without having any other effect.

You can read more about this concept here, Referential Transperency

So in simple terms what we are saying is in functional programming one of the main important blocks is using pure functions, these functions take an input and produce results based on the input provided therefore preventing side-effects. Pure functions are referential transparent meaning you can replace a call to the function with its return value.

I think at this point I can define what functional programming is then , because we have covered some fundamental concepts and it would make sense to add a definition.

Functional programming is simply constructing functions without side effects ie. writing code with pure functions.

What other concepts are important to know? Let's look at a few

Immutability

giphy-immutable.gif

Ted Lasso is telling us people change, well I am happy to announce to you that variables in functional programming do not ๐Ÿ˜….

Immutability means what it means, not being able to change the value of a variable after it has been declared.

In Scala, we have var for variable and val for value, var is mutable in Scala while val is immutable. I would advice that you stay away from var as much as you can when using Scala, using var in Scala just defeats the whole purpose of functional programming.

Recursion

giphyr.gif

Remember in functional programming we cannot mutate variables right. We use recursion in place of loops. This is because in loops you have to mutate the value of a variable until it meets a certain condition. Loops can cause side effects and we do not want that.

Unlike loops, recursion does not cause side effects. It creates new values which are acquired from the formal values, so basically, a function calling itself repeatedly and each time creating new values. It stops calling itself when a certain condition is met within the function.

Where to go from here

This article was meant to provide you with some of the basic and important concepts of functional programming. Some other concepts worth mentioning are Currying and Higher Order Functions.

If you are planing of transitioing to functional programming and you have some experience with Java then I would recommend Scala since it has a blend of OOP and functional programming. If you are into frontend development and familiar with frameworks like React, Vue, and Angular you can take a look into learning Elm. You could also just jump head straight into learning languages like Haskell, Elixir, etc my recommendations were just to help to make your transition into functional programming to be a bit smooth, the truth is there are concepts that you would come across that are totally new and it takes practice to become perfect.

Enjoy your functional programming journey!