Menu

Nakov.com logo

Thoughts on Software Engineering

Functional Programming: Overview

I recently published a free video lesson about the concepts of functional programming, where I explained and demonstrated the functional programming paradigm. Learn more at softuni.org:

Functional programming (FP) is a style of programming based on composing pure functions, while avoiding shared state, mutable data, and side-effects. It’s important, because most modern mainstream programming languages (like JavaScript, Python, Java and C#) support the functional paradigm with lambda functions and higher-order functions.

In this lesson I explain and demonstrate through live coding examples in JavaScript, Python, Java and C# the concepts of functional programming, pure functions, first-class functions, lambda functions, higher-order functions, and how to combine these concepts to implement filtering, mapping, ordering and other transformations over sequences of elements.

Functional Programming Overview: Video Lesson

What is Functional Programming?

Functional programming (FP) is programming based on composing pure functions, while avoiding shared state, mutable data, and side-effects. Functional programs are sequences of transformations of data through functions. In pure functional programming functions and programs don’t have state, which means that functions do not hold shared data. They only access their input arguments and return an output. I will give some examples in the video.

Functional programming is declarative programing approach (not imperative), which means that instead of describing an algorithm how to do something step by step, functional developers describe the result by functions and compositions of functions.

The program state flows through pure functions, where one function passes its output data as input to other function.

Pure Functions

What is a “pure function“? It is a function, which returns a value only determined by its input, without side effects. Printing something at the console or storing something in a database are examples of side effects. Therefore, using pure functional programming is often impractical.

Modern languages use elements of functional-style programming and are not purely functional.

Examples of pure functions are: the square root function: “sqrt of x“, which takes a number as input and returns another number as output, and the function “sort of list“, which takes a list as input and returns a new list as output. Both functions have no side effects: they don’t change anything; they don’t read or write external data; and they do not use state. They are pure functions.

Pure functions are the heart of the functional programming. Using “pure functions” means maintaining “consistent results“. If you invoke a pure function many times with the same input data, it will have the same consistent behavior and will return the same result, because it have no state and no interaction with the external data or components. Pure functions produce predictable results and behavior and sometimes their correctness can be mathematically proven.

This is the most important principle in functional programming: to build programs by composition of stateless pure functions without side effects.

Functional Languages

Purely functional languages (like Haskell) are unpractical for most real-world projects and are rarely used.

Modern programming languages are much more practical, so they implement the functional paradigm, along with other paradigms like structured programming and object-oriented programming.

There are many functional programming languages and languages that incorporate functional paradigms into modern software development. Most modern languages are not functional, but support concepts for functional programming.

Purely Functional Languages

Purely functional languages are unpractical and rarely used, because it is more complicated to program without maintaining a state. Purely functional developers need to switch their thinking style from the traditional “algorithmic thinking” to “functional thinking“. The program in the purely functional languages is a pure function (which calls other pure functions) without side effects. An example of purely functional language is Haskell, which is not widely used in practice, but it has a great value in learning the functional programming paradigms.

Impure Functional Languages

Impure functional languages are used more often because they allow exceptions from the concept of “pure functions” and simplify the work of developers. These languages emphasize the functional style but sometimes allow side effects.

An example of impure functional language is Clojure. It is not very popular in practical software development.

Multi-Paradigm Languages

Multi-paradigm languages combine the strengths of both the functional and the algorithmic (or imperative) world. Most of today’s widely used general-purpose programming languages are multi-paradigm. They combine multiple programing paradigms: functional programming, declarative programming, structured programming, imperative programming, object-oriented programming, component-based programming, event-driven programming, asynchronous programming, and many others.

Examples of popular general-purpose multi-paradigm programming languages are: JavaScript, C#, Python, Java, PHP, C++, Go, Swift and TypeScript.

All these languages combine multiple concepts and paradigms for structuring the program to simplify the work of developers and improve their efficiency and performance.

The Functional Paradigm in Action

This is an example, which demonstrates the functional style of programming, compared to the traditional imperative (or structured) programming style. We want to write a C# program to read several numbers, find the biggest of them and print it.

Functional Style Example in C#

To solve this problem in a functional style, we can write the following code:

Console.WriteLine(
  Console.ReadLine()
    .Split(" ")
    .Select(int.Parse)
    .Max()
);

Imperative Style Example in C#

Now, let’s see the equivalent imperative style for the same program, again in C#. This is a piece of code, written in a structured programming style (procedural style). It consists of sequence of commands and each command takes its input from a variable, calculates a new result and stores it in a variable:

var input = Console.ReadLine();
var items = input.Split(" ");
var nums = items.Select(int.Parse);
var maxNum = nums.Max();
Console.WriteLine(maxNum);

Functional Programming – Live Demo

We can see the code from the previous examples in action:

Lambda Functions

In programming, lambda functions are short expressions that transform an input into an output.

Lambda functions are typically used as arguments to other functions, and this is supported by most modern programming languages. For example, a sorting function may accept as a parameter a lambda function, which implements the comparison between two objects.

For better understanding this concept, let’s see some examples of lambda functions in JavaScript, Java, Python and C#.

The first example is a lambda function in C#:

x => 2 * x

The next example is a lambda function in JavaScript:

x => 2 * x

The next example is a lambda function in Python:

lambda x: 2 * x

First-Class Functions

JavaScript, Python, C# and Java support “first-class functions“. This concept means that functions can be stored in variables and can be passed as arguments to other functions. These languages support expressions of type “function”, which hold programming logic to transform some input into some output.

Lambda functions are the simplest way to write an expression of type “function”. Once we have a variable, which holds a function, we can invoke it. Let’s review some examples.

This example in JavaScript shows how to define a variable, which holds a lambda function as its value, and how to invoke it with certain argument:

let twice = x => 2 * x;
let d = twice(5);  // 10

The next example implements the same code in Python:

twice = lambda x: 2 * x
d = twice(5)  # 10

This is the same code in C#:

Func<int, int> twice = x => 2 * x;
var d = twice(5);  // 10

The same code can be written in Java, and it looks very similar:

Function<Integer, Integer> twice = x -> 2 * x;
var d = twice.apply(5);  // 10

First-class functions are an important concept in programming. They allow functions and methods to take other functions as arguments. And this is very powerful tool for many situations.

First-Class Functions – Live Demo

The following live demonstration illustrates how to use first-class functions in JavaScript:

Higher-Order Functions

Higher-order functions take other functions as arguments and thus they can implement abstract behavior. For example, an aggregation function may accept as an argument the aggregation operator (which is a lambda function).

Let’s see how this happens in action. We can create functions, which calculate something, but what exactly depends on their arguments.

Higher-Order Functions – Example

Let’s take an example: the function “aggregate“. It takes 3 parameters: start, end and func. The function aggregates the result from the given function over the numbers from start to end:

function aggregate(start, end, func) {
  for (var result = start, i = start+1; i <= end; i++)
    result = func(result, i);
  return result;
}

For example, the above function can multiply the numbers from 1 to 10, or it can sum the numbers from 20 to 30.

In the body of the “aggregate” function we apply the function “func” many times in a loop, for the numbers from “start” to “end“. The start number, end number and the aggregation function come as arguments.

This function is a good example, which illustrates the power of “higher-order functions” in functional programming. The function “aggregateaccepts as parameter another function, which combines two values during the aggregation process.

Invoking a Higher-Order Functions – Example

This is an example how we can invoke this higher-order function: we sum the numbers from 1 to 10. The start argument is 1. The end argument is 10. The aggregation function is “a + b“. It sums its arguments:

aggregate(1, 10, (a, b) => a + b)  // 55

This is an example how we can invoke the same higher-order function to multiply the numbers from 1 to 10:

aggregate(1, 10, (a, b) => a * b)  // 3628800

This last example demonstrates how we can append together the numbers from 1 to 10, using the same higher-order function:

aggregate(1, 10, (a, b) => '' + a + b)  // "12345678910"

The aggregation function here is different: it appends its arguments as text.

Invoking a Higher-Order Functions – Live Demo

This live code demonstration illustrates how to use higher-order functions in JavaScript. It holds the above examples:

Subscribe to My YouTube Channel

Do you like this free programming lesson? Do you want more? Subscribe to my YouTube channel to stay in touch with my free coding courses, lessons and tutorials:

Join the “Learn to Code” Community

Join the SoftUni global learn-to-code community at softuni.org to get free access to the practical exercises and the automated judge system for this course. Get free help from mentors and meet other learners. It’s free!

Happy coding!

Comments (1)

One Response to “Functional Programming: Overview”

  1. Great post! I had the same impressions of South Korea while I was there. I came to South Korea directly from Japan, where I spent 3 months. I got used to calm Japanese people waiting in the line to enter the metro and then I landed in Seoul and nearly died in the metro..
    Your budget is really small considering the fact you paid for all of your acommodation. I totally recommend CouchSurfing, I saved a lot using CS.

RSS feed for comments on this post. TrackBack URL

LEAVE A COMMENT