Higher Order Functions
Ce contenu n’est pas encore disponible dans votre langue.
Introduction
Section titled “Introduction”In Javascript, functions are values (first-class citizens). This means that they can be assigned to a variable and/or passed as a value.
const random = function () { return Math.random()}
const giveMeRandom = random // assigns random to a variableThis single piece of knowledge allows us to write functional programming in this language. In functional programming, we heavily use higher-order functions.
The concept
Section titled “The concept”Higher Order Functions is simply a function that takes another function as an argument or returns a function. This is possible because functions are first class citizens in JavaScript, which means that they can be passed as arguments, returned from other functions, and stored in variables as objects.
NB: Taking an other function as an argument is often referred as a callback function, because it is called back by the higher-order function.
NB 2: Returning a function is often referred as a currying function, because it returns a function that takes the remaining arguments.
Currying and HOF
Section titled “Currying and HOF”More on that on a later episode. Basically, it allows us to write functions that take multiple arguments, and return a function that takes the remaining arguments. This is often done in order to make a ‘specific’ function from a ‘parent’ function.
function curry(f) { // curry(f) does the currying transform return function (a) { return function (b) { return f(a, b) } }}
// usagefunction sum(a, b) { return a + b}
const curriedSum = curry(sum)
console.log(curriedSum(1)(2)) // 3NB: ⚠️ Function expression are NOT hoisted.
The power of composition
Section titled “The power of composition”One of the great advantages of using higher order functions is composition.
We can create smaller functions that only take care of one piece of logic. Then, we compose more complex functions by using different smaller functions.
This technique reduces bugs and makes our code easier to read, understand and maintain.
Below is an example of composition.
Given a sample array of numbers, we want to get:
- The average grade of this classroom
- The average grade for the boys
- The average grade for the girls
- The highest & lowest grade for the boys
- The highest & lowest grade for the girls
// The data setconst grades = [ { name: 'John', grade: 8, sex: 'M' }, { name: 'Sarah', grade: 12, sex: 'F' }, { name: 'Bob', grade: 16, sex: 'M' }, { name: 'Johnny', grade: 2, sex: 'M' }, { name: 'Ethan', grade: 4, sex: 'M' }, { name: 'Paula', grade: 18, sex: 'F' }, { name: 'Donald', grade: 5, sex: 'M' }, { name: 'Jennifer', grade: 13, sex: 'F' }, { name: 'Courtney', grade: 15, sex: 'F' }, { name: 'Jane', grade: 9, sex: 'F' },]
// The pure (simple) functionsconst isBoy = student => student.sex === 'M'
const isGirl = student => student.sex === 'F'
const getBoys = grades => grades.filter(isBoy)
const getGirls = grades => grades.filter(isGirl)
const average = grades => grades.reduce((acc, current) => acc + current.grade, 0) / grades.length
const maxGrade = grades => Math.max(...grades.map(student => student.grade))
const minGrade = grades => Math.min(...grades.map(student => student.grade))
const classroomAverage = average(grades) // 10.2const boysAverage = average(getBoys(grades)) // 7const girlsAverage = average(getGirls(grades)) // 13.4const highestGrade = maxGrade(grades) // 18const lowestGrade = minGrade(grades) // 2const highestBoysGrade = maxGrade(getBoys(grades)) // 16const lowestBoysGrade = minGrade(getBoys(grades)) // 2const highestGirlsGrade = maxGrade(getGirls(grades)) // 18const lowestGirlsGrade = minGrade(getGirls(grades)) // 9The outer functions, average for example, always take as an input the output from the inner functions. Therefore, the only condition to composition is to make sure that the output and input match (⚠️ type checking).
And because each function is responsible for only one thing, it makes this code easier to debug and to test.
HOFs in practice
Section titled “HOFs in practice”See the following TypeScript array snippets:
- Filter
- Sort
- Find
Sources
Section titled “Sources”- Eloquent Javascript on higher order
- Dam Cosset from dev.to on higher order functions in javascript
- Alex Devero on HOF in JS
- Javascript.info on Currying