Functional Programming (Part 1): First-Class Functions

Ahmad M. Hawwash
Bits and Pieces
Published in
5 min readFeb 7, 2022

--

Twins in a shirt (functions and variables)
Photo by Ron Lach from Pexels

This article is a part of a series that talks about “Functional Programming”

In the previous article in this series we discussed main programming paradigms and basic differences. In this article we’ll talk about one of the most important features (maybe the most important one) in a programming language that supports Functional style programming; First-Class functions.

Contents

  • What is a First-Class function?
  • Why First-Class functions matter

What is a First-Class function?

A Programming language is considered to have First-Class functions support when it has no restrictions/limits on how functions can be created or used.

“A programming language is said to have First-class functions when functions in that language are treated like any other variable.” — MDN

In general, programming languages impose restrictions on the ways in which computational elements can be manipulated. Elements with the fewest restrictions are said to have first-class status. Some of the “rights and privileges’’ of first-class elements:

  • Can be assigned to regular variables
  • Passed as arguments to functions
  • Returned as results of functions
  • Included in any data structures

Functions in a programming language are considered First-Class if they can be:

1. Assigned to regular variables

When functions can be assigned to any variable name, like:

2. Passed as arguments to functions

When functions can be passed like any parameter to a function, like:

We have addOne function that is treated as a variable and passed to .map function. That’s being said, addOne function is indeed a first-class function.

3. Returned as results of functions

When functions can return another function, like:

The makeCounter function returned a function and we assigned it to counter variable. Where counter variable now is holding a regular function.

4. Included in any data structures

When functions can be stored in any data structure, like:

We can store functions in arrays and as you guessed we can also store them in objects and loop through them as often.

Why First-Class functions matter

Functional programming (FP) is highly influenced by Mathematics realm. FP would love to have all Mathematics included in every line of code.

Although Math is only built with functions and variables, it’s still very powerful and expressive. That’s what FP is trying to do. Solving every single problem using functions and functions only (exactly how the big brother (Maths) would do it).

That’s why functions’ freedom (making them first-class) comes into work. When you can treat a function in a programming language as simple as a variable, that language would be much more flexible and opens a lot of rooms for improvements. Which as we mentioned earlier, FP will make your code more Predictable, Testable, Reusable, Customisable, Cacheable, Maintainable, Composable and Readable.

So, you would ask yourself “Ok I understand the relationship between FP and Mathematics, but how first-class functions would make all these benefits possible?”

Very nice question. Well, since FP depends all the way on functions’ freedom. first-class functions is the corner stone for all FP concepts, once you have the corner stone then you can build on top of it these awesome concepts (as we’ll try to do in the coming parts of the series).

Having first-class functions in a programming language would make it possible to have some awesome patterns, such as:

1. Higher-order functions

Functions are considered higher-order functions when they take functions as arguments, (like most Array utilities, .map, .filter, .reduce, .every ) and/or return a function as a result (Exactly like makeCounter).

2. Closures

A closure is a function returned by a “parent” function and has access to the parent function’s internal state. Like our previous example of makeCounter.

To elaborate more, let’s give it another example:

Let’s explain that line by line:

Line 1: The add is a function that takes the first param x, and returns an anonymous function that takes the second param y, and returns x + y.

Line 3: Executing add(5) will return a function with a value of 5 inside it. Compiler/Optimiser will understand it exactly like this:

const add5 = (y) => 5 + y 

Line 4: Exactly like line 3. Executing add(10) will return a function with a value of 10 inside it. Compiler/Optimiser will understand it exactly like this:

const add10 = (y) => 10 + y

Line 6 & Line 7: They are just normal function calls to the previously “dynamically” created functions of add5 and add10.

Ok, that’s cool. After understanding what each line does, what are the actual technical terms for add, add5 and add10:

  • add is a higher-order function. Why? because it returns a function
  • But add5 and add10 are closures. Why? Because they have values 5 and 10 respectively enclosed (bound) in their parent’s lexical scope and still accessible by them. (That’s why when we add5(1) it will use the the already passed 5 to add)

(Note 1: The relationship between a closure and a higher-order function, is like parent and child, we will not be able to have a closure without a higher-order function)

(Note 2: I found something interesting about closures while writing this article)

3. Currying

It’s a mechanism of applying the lazy evaluation concept. Which we’ll discuss it in details later on…

Conclusion

First-class function is not a pattern, it is just a feature in a programming language. That feature would allow treating functions easily as variables, and moved around without restrictions. Having that feature would make the language more powerful and FP-ready. Where we can be build very powerful utilities using that feature, like higher-order functions, closures, currying and more…

Thanks a lot for taking time reading through this article. I’m cooking the next ones in the series. Please feedback me and let me know what you think in the comments about this article or the series.

This is an article in a series of articles talking about Functional Programming

In this series of articles we cover the main concepts of Functional Programming. At the end of the series, you’ll be able to tackle problems in a more functional approach.

This series discusses:

0. A Brief Comparison Between Programming Paradigms

  1. First Class functions (this article)
  2. Pure functions
  3. Currying
  4. Composition
  5. Functors
  6. Monads

--

--

twitter: @AhmadMHawwash. Frontend engineering consultant @Mirado Stockholm. With interest in JS, TS, FP, React, Nextjs, Clean Code, Clean Architecture…