Discover Functional JavaScript was named one of the best new Functional Programming books by BookAuthority!
In JavaScript, functions are first-class objects, which means they can be:
- stored in a variable, object, or array
- passed as an argument to a function
- returned from a function
Storing a function
Functions can be stored in three ways:
- store in a variable :
let fn = function doSomething[] {}
- store in an object :
let obj = { doSomething : function[]{} }
- store in an array :
arr.push[function doSomething[] {}]
In the first and third example, I used a named function expression.
The function expression defines a function as part of a larger expression. The line of code doesn’t start with function
.
Function as an argument
In the next example, the function doSomething
is sent as an argument to doAction[]
.
doAction[function doSomething[]{}];
doSomething
is a callback.
A callback is a function passed as an argument to another function.
Higher order functions
A higher order function is a function that takes another function as an input, returns a function or does both.
You can find more in the Discover Functional JavaScript book.
For more on applying functional programming techniques in React take a look at Functional React.
Learn functional React, in a project-based way, with Functional Architecture with React and Redux.
Follow on Twitter
ADVERTISEMENT
ADVERTISEMENT
Author of Discover Functional JavaScript and Functional React. Enthusiastic about sharing ideas.
If you read this far, tweet to the author to show them you care. Tweet a thanks
Learn to code for free. freeCodeCamp's open source curriculum has helped more than 40,000 people get jobs as developers. Get started
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
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 matterFunctional 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
,
const add10 = [y] => 10 + y
0, const add10 = [y] => 10 + y
1 ] 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
const add10 = [y] => 10 + y
4 is a function that takes the first param const add10 = [y] => 10 + y
5, and returns an anonymous function that takes the second param const add10 = [y] => 10 + y
6, and returns const add10 = [y] => 10 + y
7.Line 3: Executing
const add10 = [y] => 10 + y
8 will return a function with a value of const add10 = [y] => 10 + y
9 inside it. Compiler/Optimiser will understand it exactly like this:const add5 = [y] => 5 + y
Line 4: Exactly like line 3. Executing addOne
0 will return a function with a value of addOne
1 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 addOne
2 and addOne
3.
Ok, that’s cool. After understanding what each line does, what are the actual technical terms for
const add10 = [y] => 10 + y
4, addOne
2 and addOne
3:const add10 = [y] => 10 + y
4 is a higher-order function. Why? because it returns a function- But
addOne
2 andaddOne
3 are closures. Why? Because they have valuesconst add10 = [y] => 10 + y
9 andaddOne
1 respectively enclosed [bound] in their parent’s lexical scope and still accessible by them. [That’s why when we.map
2 it will use the the already passedconst add10 = [y] => 10 + y
9 toconst add10 = [y] => 10 + y
4]
[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…
ConclusionFirst-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.